From 5550bebcaa8e38a7c0ed61570bfee0cb5f24d3e5 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Mon, 9 Feb 2015 00:01:55 +0100 Subject: [PATCH 01/76] Move remaning compile-fail tests that are rejected by the parser to parse-fail --- src/test/{parse-fail => compile-fail}/mod_file_disambig.rs | 0 src/test/{parse-fail => compile-fail}/mod_file_not_owning.rs | 0 .../{compile-fail => parse-fail}/ascii-only-character-escape.rs | 0 src/test/{compile-fail => parse-fail}/attr-before-eof.rs | 0 src/test/{compile-fail => parse-fail}/attr-before-ext.rs | 0 src/test/{compile-fail => parse-fail}/attr-before-let.rs | 0 src/test/{compile-fail => parse-fail}/attr-before-stmt.rs | 0 src/test/{compile-fail => parse-fail}/attr-dangling-in-fn.rs | 0 src/test/{compile-fail => parse-fail}/attr-dangling-in-mod.rs | 0 src/test/{compile-fail => parse-fail}/attr.rs | 0 src/test/{compile-fail => parse-fail}/attrs-after-extern-mod.rs | 0 src/test/{compile-fail => parse-fail}/bad-char-literals.rs | 0 src/test/{compile-fail => parse-fail}/bad-lit-suffixes.rs | 0 src/test/{compile-fail => parse-fail}/bad-value-ident-false.rs | 0 src/test/{compile-fail => parse-fail}/bad-value-ident-true.rs | 0 src/test/{compile-fail => parse-fail}/doc-before-attr.rs | 0 src/test/{compile-fail => parse-fail}/doc-before-eof.rs | 0 src/test/{compile-fail => parse-fail}/doc-before-extern-rbrace.rs | 0 src/test/{compile-fail => parse-fail}/doc-before-macro.rs | 0 src/test/{compile-fail => parse-fail}/doc-before-rbrace.rs | 0 src/test/{compile-fail => parse-fail}/doc-before-semi.rs | 0 .../extern-crate-as-no-string-help.rs | 0 .../{compile-fail => parse-fail}/generic-non-trailing-defaults.rs | 0 .../{compile-fail => parse-fail}/int-literal-too-large-span.rs | 0 src/test/{compile-fail => parse-fail}/issue-10412.rs | 0 src/test/{compile-fail => parse-fail}/issue-12560-1.rs | 0 src/test/{compile-fail => parse-fail}/issue-14182.rs | 0 src/test/{compile-fail => parse-fail}/issue-17383.rs | 0 src/test/{compile-fail => parse-fail}/issue-17718-const-mut.rs | 0 src/test/{compile-fail => parse-fail}/issue-1802-2.rs | 0 src/test/{compile-fail => parse-fail}/issue-5544-a.rs | 0 src/test/{compile-fail => parse-fail}/issue-5544-b.rs | 0 src/test/{compile-fail => parse-fail}/issue-8537.rs | 0 src/test/{compile-fail => parse-fail}/keyword-as-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-break-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-else-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-enum-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-extern-as-identifier.rs | 0 src/test/{compile-fail => parse-fail}/keyword-fn-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-for-as-identifier.rs | 0 src/test/{compile-fail => parse-fail}/keyword-if-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-impl-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-let-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-loop-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-match-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-mod-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-pub-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-return-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-self-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-static-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-struct-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-super-as-identifier.rs | 0 src/test/{compile-fail => parse-fail}/keyword-super.rs | 0 .../{compile-fail => parse-fail}/keyword-trait-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-type-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-unsafe-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-use-as-identifier.rs | 0 .../{compile-fail => parse-fail}/keyword-while-as-identifier.rs | 0 src/test/{compile-fail => parse-fail}/keyword.rs | 0 .../keywords-followed-by-double-colon.rs | 0 src/test/{compile-fail => parse-fail}/lex-bad-numeric-literals.rs | 0 .../lex-bare-cr-string-literal-doc-comment.rs | 0 src/test/{compile-fail => parse-fail}/lifetime-no-keyword.rs | 0 src/test/{compile-fail => parse-fail}/lifetime-obsoleted-self.rs | 0 .../{compile-fail => parse-fail}/macros-no-semicolon-items.rs | 0 src/test/{compile-fail => parse-fail}/no-binary-float-literal.rs | 0 src/test/{compile-fail => parse-fail}/no-hex-float-literal.rs | 0 src/test/{compile-fail => parse-fail}/no-unsafe-self.rs | 0 src/test/{compile-fail => parse-fail}/non-str-meta.rs | 0 src/test/{compile-fail => parse-fail}/obsolete-for-sized.rs | 0 src/test/{compile-fail => parse-fail}/obsolete-proc.rs | 0 src/test/{compile-fail => parse-fail}/qquote-1.rs | 0 src/test/{compile-fail => parse-fail}/qquote-2.rs | 0 src/test/{compile-fail => parse-fail}/regions-fn-bound.rs | 0 .../require-parens-for-chained-comparison.rs | 0 src/test/{compile-fail => parse-fail}/struct-no-fields-2.rs | 0 src/test/{compile-fail => parse-fail}/struct-no-fields-3.rs | 0 src/test/{compile-fail => parse-fail}/struct-no-fields-4.rs | 0 src/test/{compile-fail => parse-fail}/struct-no-fields-5.rs | 0 src/test/{compile-fail => parse-fail}/struct-variant-no-fields.rs | 0 src/test/{compile-fail => parse-fail}/struct-variant-no-pub.rs | 0 src/test/{compile-fail => parse-fail}/syntax-trait-polarity.rs | 0 .../{compile-fail => parse-fail}/tag-variant-disr-non-nullary.rs | 0 .../trailing-carriage-return-in-string.rs | 0 src/test/{compile-fail => parse-fail}/trailing-plus-in-bounds.rs | 0 src/test/{compile-fail => parse-fail}/trait-bounds-not-on-impl.rs | 0 .../type-parameters-in-field-exprs.rs | 0 src/test/{compile-fail => parse-fail}/unsized2.rs | 0 src/test/{compile-fail => parse-fail}/virtual-structs.rs | 0 .../where-clauses-no-bounds-or-predicates.rs | 0 90 files changed, 0 insertions(+), 0 deletions(-) rename src/test/{parse-fail => compile-fail}/mod_file_disambig.rs (100%) rename src/test/{parse-fail => compile-fail}/mod_file_not_owning.rs (100%) rename src/test/{compile-fail => parse-fail}/ascii-only-character-escape.rs (100%) rename src/test/{compile-fail => parse-fail}/attr-before-eof.rs (100%) rename src/test/{compile-fail => parse-fail}/attr-before-ext.rs (100%) rename src/test/{compile-fail => parse-fail}/attr-before-let.rs (100%) rename src/test/{compile-fail => parse-fail}/attr-before-stmt.rs (100%) rename src/test/{compile-fail => parse-fail}/attr-dangling-in-fn.rs (100%) rename src/test/{compile-fail => parse-fail}/attr-dangling-in-mod.rs (100%) rename src/test/{compile-fail => parse-fail}/attr.rs (100%) rename src/test/{compile-fail => parse-fail}/attrs-after-extern-mod.rs (100%) rename src/test/{compile-fail => parse-fail}/bad-char-literals.rs (100%) rename src/test/{compile-fail => parse-fail}/bad-lit-suffixes.rs (100%) rename src/test/{compile-fail => parse-fail}/bad-value-ident-false.rs (100%) rename src/test/{compile-fail => parse-fail}/bad-value-ident-true.rs (100%) rename src/test/{compile-fail => parse-fail}/doc-before-attr.rs (100%) rename src/test/{compile-fail => parse-fail}/doc-before-eof.rs (100%) rename src/test/{compile-fail => parse-fail}/doc-before-extern-rbrace.rs (100%) rename src/test/{compile-fail => parse-fail}/doc-before-macro.rs (100%) rename src/test/{compile-fail => parse-fail}/doc-before-rbrace.rs (100%) rename src/test/{compile-fail => parse-fail}/doc-before-semi.rs (100%) rename src/test/{compile-fail => parse-fail}/extern-crate-as-no-string-help.rs (100%) rename src/test/{compile-fail => parse-fail}/generic-non-trailing-defaults.rs (100%) rename src/test/{compile-fail => parse-fail}/int-literal-too-large-span.rs (100%) rename src/test/{compile-fail => parse-fail}/issue-10412.rs (100%) rename src/test/{compile-fail => parse-fail}/issue-12560-1.rs (100%) rename src/test/{compile-fail => parse-fail}/issue-14182.rs (100%) rename src/test/{compile-fail => parse-fail}/issue-17383.rs (100%) rename src/test/{compile-fail => parse-fail}/issue-17718-const-mut.rs (100%) rename src/test/{compile-fail => parse-fail}/issue-1802-2.rs (100%) rename src/test/{compile-fail => parse-fail}/issue-5544-a.rs (100%) rename src/test/{compile-fail => parse-fail}/issue-5544-b.rs (100%) rename src/test/{compile-fail => parse-fail}/issue-8537.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-as-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-break-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-else-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-enum-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-extern-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-fn-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-for-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-if-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-impl-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-let-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-loop-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-match-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-mod-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-pub-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-return-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-self-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-static-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-struct-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-super-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-super.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-trait-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-type-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-unsafe-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-use-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword-while-as-identifier.rs (100%) rename src/test/{compile-fail => parse-fail}/keyword.rs (100%) rename src/test/{compile-fail => parse-fail}/keywords-followed-by-double-colon.rs (100%) rename src/test/{compile-fail => parse-fail}/lex-bad-numeric-literals.rs (100%) rename src/test/{compile-fail => parse-fail}/lex-bare-cr-string-literal-doc-comment.rs (100%) rename src/test/{compile-fail => parse-fail}/lifetime-no-keyword.rs (100%) rename src/test/{compile-fail => parse-fail}/lifetime-obsoleted-self.rs (100%) rename src/test/{compile-fail => parse-fail}/macros-no-semicolon-items.rs (100%) rename src/test/{compile-fail => parse-fail}/no-binary-float-literal.rs (100%) rename src/test/{compile-fail => parse-fail}/no-hex-float-literal.rs (100%) rename src/test/{compile-fail => parse-fail}/no-unsafe-self.rs (100%) rename src/test/{compile-fail => parse-fail}/non-str-meta.rs (100%) rename src/test/{compile-fail => parse-fail}/obsolete-for-sized.rs (100%) rename src/test/{compile-fail => parse-fail}/obsolete-proc.rs (100%) rename src/test/{compile-fail => parse-fail}/qquote-1.rs (100%) rename src/test/{compile-fail => parse-fail}/qquote-2.rs (100%) rename src/test/{compile-fail => parse-fail}/regions-fn-bound.rs (100%) rename src/test/{compile-fail => parse-fail}/require-parens-for-chained-comparison.rs (100%) rename src/test/{compile-fail => parse-fail}/struct-no-fields-2.rs (100%) rename src/test/{compile-fail => parse-fail}/struct-no-fields-3.rs (100%) rename src/test/{compile-fail => parse-fail}/struct-no-fields-4.rs (100%) rename src/test/{compile-fail => parse-fail}/struct-no-fields-5.rs (100%) rename src/test/{compile-fail => parse-fail}/struct-variant-no-fields.rs (100%) rename src/test/{compile-fail => parse-fail}/struct-variant-no-pub.rs (100%) rename src/test/{compile-fail => parse-fail}/syntax-trait-polarity.rs (100%) rename src/test/{compile-fail => parse-fail}/tag-variant-disr-non-nullary.rs (100%) rename src/test/{compile-fail => parse-fail}/trailing-carriage-return-in-string.rs (100%) rename src/test/{compile-fail => parse-fail}/trailing-plus-in-bounds.rs (100%) rename src/test/{compile-fail => parse-fail}/trait-bounds-not-on-impl.rs (100%) rename src/test/{compile-fail => parse-fail}/type-parameters-in-field-exprs.rs (100%) rename src/test/{compile-fail => parse-fail}/unsized2.rs (100%) rename src/test/{compile-fail => parse-fail}/virtual-structs.rs (100%) rename src/test/{compile-fail => parse-fail}/where-clauses-no-bounds-or-predicates.rs (100%) diff --git a/src/test/parse-fail/mod_file_disambig.rs b/src/test/compile-fail/mod_file_disambig.rs similarity index 100% rename from src/test/parse-fail/mod_file_disambig.rs rename to src/test/compile-fail/mod_file_disambig.rs diff --git a/src/test/parse-fail/mod_file_not_owning.rs b/src/test/compile-fail/mod_file_not_owning.rs similarity index 100% rename from src/test/parse-fail/mod_file_not_owning.rs rename to src/test/compile-fail/mod_file_not_owning.rs diff --git a/src/test/compile-fail/ascii-only-character-escape.rs b/src/test/parse-fail/ascii-only-character-escape.rs similarity index 100% rename from src/test/compile-fail/ascii-only-character-escape.rs rename to src/test/parse-fail/ascii-only-character-escape.rs diff --git a/src/test/compile-fail/attr-before-eof.rs b/src/test/parse-fail/attr-before-eof.rs similarity index 100% rename from src/test/compile-fail/attr-before-eof.rs rename to src/test/parse-fail/attr-before-eof.rs diff --git a/src/test/compile-fail/attr-before-ext.rs b/src/test/parse-fail/attr-before-ext.rs similarity index 100% rename from src/test/compile-fail/attr-before-ext.rs rename to src/test/parse-fail/attr-before-ext.rs diff --git a/src/test/compile-fail/attr-before-let.rs b/src/test/parse-fail/attr-before-let.rs similarity index 100% rename from src/test/compile-fail/attr-before-let.rs rename to src/test/parse-fail/attr-before-let.rs diff --git a/src/test/compile-fail/attr-before-stmt.rs b/src/test/parse-fail/attr-before-stmt.rs similarity index 100% rename from src/test/compile-fail/attr-before-stmt.rs rename to src/test/parse-fail/attr-before-stmt.rs diff --git a/src/test/compile-fail/attr-dangling-in-fn.rs b/src/test/parse-fail/attr-dangling-in-fn.rs similarity index 100% rename from src/test/compile-fail/attr-dangling-in-fn.rs rename to src/test/parse-fail/attr-dangling-in-fn.rs diff --git a/src/test/compile-fail/attr-dangling-in-mod.rs b/src/test/parse-fail/attr-dangling-in-mod.rs similarity index 100% rename from src/test/compile-fail/attr-dangling-in-mod.rs rename to src/test/parse-fail/attr-dangling-in-mod.rs diff --git a/src/test/compile-fail/attr.rs b/src/test/parse-fail/attr.rs similarity index 100% rename from src/test/compile-fail/attr.rs rename to src/test/parse-fail/attr.rs diff --git a/src/test/compile-fail/attrs-after-extern-mod.rs b/src/test/parse-fail/attrs-after-extern-mod.rs similarity index 100% rename from src/test/compile-fail/attrs-after-extern-mod.rs rename to src/test/parse-fail/attrs-after-extern-mod.rs diff --git a/src/test/compile-fail/bad-char-literals.rs b/src/test/parse-fail/bad-char-literals.rs similarity index 100% rename from src/test/compile-fail/bad-char-literals.rs rename to src/test/parse-fail/bad-char-literals.rs diff --git a/src/test/compile-fail/bad-lit-suffixes.rs b/src/test/parse-fail/bad-lit-suffixes.rs similarity index 100% rename from src/test/compile-fail/bad-lit-suffixes.rs rename to src/test/parse-fail/bad-lit-suffixes.rs diff --git a/src/test/compile-fail/bad-value-ident-false.rs b/src/test/parse-fail/bad-value-ident-false.rs similarity index 100% rename from src/test/compile-fail/bad-value-ident-false.rs rename to src/test/parse-fail/bad-value-ident-false.rs diff --git a/src/test/compile-fail/bad-value-ident-true.rs b/src/test/parse-fail/bad-value-ident-true.rs similarity index 100% rename from src/test/compile-fail/bad-value-ident-true.rs rename to src/test/parse-fail/bad-value-ident-true.rs diff --git a/src/test/compile-fail/doc-before-attr.rs b/src/test/parse-fail/doc-before-attr.rs similarity index 100% rename from src/test/compile-fail/doc-before-attr.rs rename to src/test/parse-fail/doc-before-attr.rs diff --git a/src/test/compile-fail/doc-before-eof.rs b/src/test/parse-fail/doc-before-eof.rs similarity index 100% rename from src/test/compile-fail/doc-before-eof.rs rename to src/test/parse-fail/doc-before-eof.rs diff --git a/src/test/compile-fail/doc-before-extern-rbrace.rs b/src/test/parse-fail/doc-before-extern-rbrace.rs similarity index 100% rename from src/test/compile-fail/doc-before-extern-rbrace.rs rename to src/test/parse-fail/doc-before-extern-rbrace.rs diff --git a/src/test/compile-fail/doc-before-macro.rs b/src/test/parse-fail/doc-before-macro.rs similarity index 100% rename from src/test/compile-fail/doc-before-macro.rs rename to src/test/parse-fail/doc-before-macro.rs diff --git a/src/test/compile-fail/doc-before-rbrace.rs b/src/test/parse-fail/doc-before-rbrace.rs similarity index 100% rename from src/test/compile-fail/doc-before-rbrace.rs rename to src/test/parse-fail/doc-before-rbrace.rs diff --git a/src/test/compile-fail/doc-before-semi.rs b/src/test/parse-fail/doc-before-semi.rs similarity index 100% rename from src/test/compile-fail/doc-before-semi.rs rename to src/test/parse-fail/doc-before-semi.rs diff --git a/src/test/compile-fail/extern-crate-as-no-string-help.rs b/src/test/parse-fail/extern-crate-as-no-string-help.rs similarity index 100% rename from src/test/compile-fail/extern-crate-as-no-string-help.rs rename to src/test/parse-fail/extern-crate-as-no-string-help.rs diff --git a/src/test/compile-fail/generic-non-trailing-defaults.rs b/src/test/parse-fail/generic-non-trailing-defaults.rs similarity index 100% rename from src/test/compile-fail/generic-non-trailing-defaults.rs rename to src/test/parse-fail/generic-non-trailing-defaults.rs diff --git a/src/test/compile-fail/int-literal-too-large-span.rs b/src/test/parse-fail/int-literal-too-large-span.rs similarity index 100% rename from src/test/compile-fail/int-literal-too-large-span.rs rename to src/test/parse-fail/int-literal-too-large-span.rs diff --git a/src/test/compile-fail/issue-10412.rs b/src/test/parse-fail/issue-10412.rs similarity index 100% rename from src/test/compile-fail/issue-10412.rs rename to src/test/parse-fail/issue-10412.rs diff --git a/src/test/compile-fail/issue-12560-1.rs b/src/test/parse-fail/issue-12560-1.rs similarity index 100% rename from src/test/compile-fail/issue-12560-1.rs rename to src/test/parse-fail/issue-12560-1.rs diff --git a/src/test/compile-fail/issue-14182.rs b/src/test/parse-fail/issue-14182.rs similarity index 100% rename from src/test/compile-fail/issue-14182.rs rename to src/test/parse-fail/issue-14182.rs diff --git a/src/test/compile-fail/issue-17383.rs b/src/test/parse-fail/issue-17383.rs similarity index 100% rename from src/test/compile-fail/issue-17383.rs rename to src/test/parse-fail/issue-17383.rs diff --git a/src/test/compile-fail/issue-17718-const-mut.rs b/src/test/parse-fail/issue-17718-const-mut.rs similarity index 100% rename from src/test/compile-fail/issue-17718-const-mut.rs rename to src/test/parse-fail/issue-17718-const-mut.rs diff --git a/src/test/compile-fail/issue-1802-2.rs b/src/test/parse-fail/issue-1802-2.rs similarity index 100% rename from src/test/compile-fail/issue-1802-2.rs rename to src/test/parse-fail/issue-1802-2.rs diff --git a/src/test/compile-fail/issue-5544-a.rs b/src/test/parse-fail/issue-5544-a.rs similarity index 100% rename from src/test/compile-fail/issue-5544-a.rs rename to src/test/parse-fail/issue-5544-a.rs diff --git a/src/test/compile-fail/issue-5544-b.rs b/src/test/parse-fail/issue-5544-b.rs similarity index 100% rename from src/test/compile-fail/issue-5544-b.rs rename to src/test/parse-fail/issue-5544-b.rs diff --git a/src/test/compile-fail/issue-8537.rs b/src/test/parse-fail/issue-8537.rs similarity index 100% rename from src/test/compile-fail/issue-8537.rs rename to src/test/parse-fail/issue-8537.rs diff --git a/src/test/compile-fail/keyword-as-as-identifier.rs b/src/test/parse-fail/keyword-as-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-as-as-identifier.rs rename to src/test/parse-fail/keyword-as-as-identifier.rs diff --git a/src/test/compile-fail/keyword-break-as-identifier.rs b/src/test/parse-fail/keyword-break-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-break-as-identifier.rs rename to src/test/parse-fail/keyword-break-as-identifier.rs diff --git a/src/test/compile-fail/keyword-else-as-identifier.rs b/src/test/parse-fail/keyword-else-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-else-as-identifier.rs rename to src/test/parse-fail/keyword-else-as-identifier.rs diff --git a/src/test/compile-fail/keyword-enum-as-identifier.rs b/src/test/parse-fail/keyword-enum-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-enum-as-identifier.rs rename to src/test/parse-fail/keyword-enum-as-identifier.rs diff --git a/src/test/compile-fail/keyword-extern-as-identifier.rs b/src/test/parse-fail/keyword-extern-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-extern-as-identifier.rs rename to src/test/parse-fail/keyword-extern-as-identifier.rs diff --git a/src/test/compile-fail/keyword-fn-as-identifier.rs b/src/test/parse-fail/keyword-fn-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-fn-as-identifier.rs rename to src/test/parse-fail/keyword-fn-as-identifier.rs diff --git a/src/test/compile-fail/keyword-for-as-identifier.rs b/src/test/parse-fail/keyword-for-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-for-as-identifier.rs rename to src/test/parse-fail/keyword-for-as-identifier.rs diff --git a/src/test/compile-fail/keyword-if-as-identifier.rs b/src/test/parse-fail/keyword-if-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-if-as-identifier.rs rename to src/test/parse-fail/keyword-if-as-identifier.rs diff --git a/src/test/compile-fail/keyword-impl-as-identifier.rs b/src/test/parse-fail/keyword-impl-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-impl-as-identifier.rs rename to src/test/parse-fail/keyword-impl-as-identifier.rs diff --git a/src/test/compile-fail/keyword-let-as-identifier.rs b/src/test/parse-fail/keyword-let-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-let-as-identifier.rs rename to src/test/parse-fail/keyword-let-as-identifier.rs diff --git a/src/test/compile-fail/keyword-loop-as-identifier.rs b/src/test/parse-fail/keyword-loop-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-loop-as-identifier.rs rename to src/test/parse-fail/keyword-loop-as-identifier.rs diff --git a/src/test/compile-fail/keyword-match-as-identifier.rs b/src/test/parse-fail/keyword-match-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-match-as-identifier.rs rename to src/test/parse-fail/keyword-match-as-identifier.rs diff --git a/src/test/compile-fail/keyword-mod-as-identifier.rs b/src/test/parse-fail/keyword-mod-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-mod-as-identifier.rs rename to src/test/parse-fail/keyword-mod-as-identifier.rs diff --git a/src/test/compile-fail/keyword-pub-as-identifier.rs b/src/test/parse-fail/keyword-pub-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-pub-as-identifier.rs rename to src/test/parse-fail/keyword-pub-as-identifier.rs diff --git a/src/test/compile-fail/keyword-return-as-identifier.rs b/src/test/parse-fail/keyword-return-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-return-as-identifier.rs rename to src/test/parse-fail/keyword-return-as-identifier.rs diff --git a/src/test/compile-fail/keyword-self-as-identifier.rs b/src/test/parse-fail/keyword-self-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-self-as-identifier.rs rename to src/test/parse-fail/keyword-self-as-identifier.rs diff --git a/src/test/compile-fail/keyword-static-as-identifier.rs b/src/test/parse-fail/keyword-static-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-static-as-identifier.rs rename to src/test/parse-fail/keyword-static-as-identifier.rs diff --git a/src/test/compile-fail/keyword-struct-as-identifier.rs b/src/test/parse-fail/keyword-struct-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-struct-as-identifier.rs rename to src/test/parse-fail/keyword-struct-as-identifier.rs diff --git a/src/test/compile-fail/keyword-super-as-identifier.rs b/src/test/parse-fail/keyword-super-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-super-as-identifier.rs rename to src/test/parse-fail/keyword-super-as-identifier.rs diff --git a/src/test/compile-fail/keyword-super.rs b/src/test/parse-fail/keyword-super.rs similarity index 100% rename from src/test/compile-fail/keyword-super.rs rename to src/test/parse-fail/keyword-super.rs diff --git a/src/test/compile-fail/keyword-trait-as-identifier.rs b/src/test/parse-fail/keyword-trait-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-trait-as-identifier.rs rename to src/test/parse-fail/keyword-trait-as-identifier.rs diff --git a/src/test/compile-fail/keyword-type-as-identifier.rs b/src/test/parse-fail/keyword-type-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-type-as-identifier.rs rename to src/test/parse-fail/keyword-type-as-identifier.rs diff --git a/src/test/compile-fail/keyword-unsafe-as-identifier.rs b/src/test/parse-fail/keyword-unsafe-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-unsafe-as-identifier.rs rename to src/test/parse-fail/keyword-unsafe-as-identifier.rs diff --git a/src/test/compile-fail/keyword-use-as-identifier.rs b/src/test/parse-fail/keyword-use-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-use-as-identifier.rs rename to src/test/parse-fail/keyword-use-as-identifier.rs diff --git a/src/test/compile-fail/keyword-while-as-identifier.rs b/src/test/parse-fail/keyword-while-as-identifier.rs similarity index 100% rename from src/test/compile-fail/keyword-while-as-identifier.rs rename to src/test/parse-fail/keyword-while-as-identifier.rs diff --git a/src/test/compile-fail/keyword.rs b/src/test/parse-fail/keyword.rs similarity index 100% rename from src/test/compile-fail/keyword.rs rename to src/test/parse-fail/keyword.rs diff --git a/src/test/compile-fail/keywords-followed-by-double-colon.rs b/src/test/parse-fail/keywords-followed-by-double-colon.rs similarity index 100% rename from src/test/compile-fail/keywords-followed-by-double-colon.rs rename to src/test/parse-fail/keywords-followed-by-double-colon.rs diff --git a/src/test/compile-fail/lex-bad-numeric-literals.rs b/src/test/parse-fail/lex-bad-numeric-literals.rs similarity index 100% rename from src/test/compile-fail/lex-bad-numeric-literals.rs rename to src/test/parse-fail/lex-bad-numeric-literals.rs diff --git a/src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs b/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs similarity index 100% rename from src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs rename to src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs diff --git a/src/test/compile-fail/lifetime-no-keyword.rs b/src/test/parse-fail/lifetime-no-keyword.rs similarity index 100% rename from src/test/compile-fail/lifetime-no-keyword.rs rename to src/test/parse-fail/lifetime-no-keyword.rs diff --git a/src/test/compile-fail/lifetime-obsoleted-self.rs b/src/test/parse-fail/lifetime-obsoleted-self.rs similarity index 100% rename from src/test/compile-fail/lifetime-obsoleted-self.rs rename to src/test/parse-fail/lifetime-obsoleted-self.rs diff --git a/src/test/compile-fail/macros-no-semicolon-items.rs b/src/test/parse-fail/macros-no-semicolon-items.rs similarity index 100% rename from src/test/compile-fail/macros-no-semicolon-items.rs rename to src/test/parse-fail/macros-no-semicolon-items.rs diff --git a/src/test/compile-fail/no-binary-float-literal.rs b/src/test/parse-fail/no-binary-float-literal.rs similarity index 100% rename from src/test/compile-fail/no-binary-float-literal.rs rename to src/test/parse-fail/no-binary-float-literal.rs diff --git a/src/test/compile-fail/no-hex-float-literal.rs b/src/test/parse-fail/no-hex-float-literal.rs similarity index 100% rename from src/test/compile-fail/no-hex-float-literal.rs rename to src/test/parse-fail/no-hex-float-literal.rs diff --git a/src/test/compile-fail/no-unsafe-self.rs b/src/test/parse-fail/no-unsafe-self.rs similarity index 100% rename from src/test/compile-fail/no-unsafe-self.rs rename to src/test/parse-fail/no-unsafe-self.rs diff --git a/src/test/compile-fail/non-str-meta.rs b/src/test/parse-fail/non-str-meta.rs similarity index 100% rename from src/test/compile-fail/non-str-meta.rs rename to src/test/parse-fail/non-str-meta.rs diff --git a/src/test/compile-fail/obsolete-for-sized.rs b/src/test/parse-fail/obsolete-for-sized.rs similarity index 100% rename from src/test/compile-fail/obsolete-for-sized.rs rename to src/test/parse-fail/obsolete-for-sized.rs diff --git a/src/test/compile-fail/obsolete-proc.rs b/src/test/parse-fail/obsolete-proc.rs similarity index 100% rename from src/test/compile-fail/obsolete-proc.rs rename to src/test/parse-fail/obsolete-proc.rs diff --git a/src/test/compile-fail/qquote-1.rs b/src/test/parse-fail/qquote-1.rs similarity index 100% rename from src/test/compile-fail/qquote-1.rs rename to src/test/parse-fail/qquote-1.rs diff --git a/src/test/compile-fail/qquote-2.rs b/src/test/parse-fail/qquote-2.rs similarity index 100% rename from src/test/compile-fail/qquote-2.rs rename to src/test/parse-fail/qquote-2.rs diff --git a/src/test/compile-fail/regions-fn-bound.rs b/src/test/parse-fail/regions-fn-bound.rs similarity index 100% rename from src/test/compile-fail/regions-fn-bound.rs rename to src/test/parse-fail/regions-fn-bound.rs diff --git a/src/test/compile-fail/require-parens-for-chained-comparison.rs b/src/test/parse-fail/require-parens-for-chained-comparison.rs similarity index 100% rename from src/test/compile-fail/require-parens-for-chained-comparison.rs rename to src/test/parse-fail/require-parens-for-chained-comparison.rs diff --git a/src/test/compile-fail/struct-no-fields-2.rs b/src/test/parse-fail/struct-no-fields-2.rs similarity index 100% rename from src/test/compile-fail/struct-no-fields-2.rs rename to src/test/parse-fail/struct-no-fields-2.rs diff --git a/src/test/compile-fail/struct-no-fields-3.rs b/src/test/parse-fail/struct-no-fields-3.rs similarity index 100% rename from src/test/compile-fail/struct-no-fields-3.rs rename to src/test/parse-fail/struct-no-fields-3.rs diff --git a/src/test/compile-fail/struct-no-fields-4.rs b/src/test/parse-fail/struct-no-fields-4.rs similarity index 100% rename from src/test/compile-fail/struct-no-fields-4.rs rename to src/test/parse-fail/struct-no-fields-4.rs diff --git a/src/test/compile-fail/struct-no-fields-5.rs b/src/test/parse-fail/struct-no-fields-5.rs similarity index 100% rename from src/test/compile-fail/struct-no-fields-5.rs rename to src/test/parse-fail/struct-no-fields-5.rs diff --git a/src/test/compile-fail/struct-variant-no-fields.rs b/src/test/parse-fail/struct-variant-no-fields.rs similarity index 100% rename from src/test/compile-fail/struct-variant-no-fields.rs rename to src/test/parse-fail/struct-variant-no-fields.rs diff --git a/src/test/compile-fail/struct-variant-no-pub.rs b/src/test/parse-fail/struct-variant-no-pub.rs similarity index 100% rename from src/test/compile-fail/struct-variant-no-pub.rs rename to src/test/parse-fail/struct-variant-no-pub.rs diff --git a/src/test/compile-fail/syntax-trait-polarity.rs b/src/test/parse-fail/syntax-trait-polarity.rs similarity index 100% rename from src/test/compile-fail/syntax-trait-polarity.rs rename to src/test/parse-fail/syntax-trait-polarity.rs diff --git a/src/test/compile-fail/tag-variant-disr-non-nullary.rs b/src/test/parse-fail/tag-variant-disr-non-nullary.rs similarity index 100% rename from src/test/compile-fail/tag-variant-disr-non-nullary.rs rename to src/test/parse-fail/tag-variant-disr-non-nullary.rs diff --git a/src/test/compile-fail/trailing-carriage-return-in-string.rs b/src/test/parse-fail/trailing-carriage-return-in-string.rs similarity index 100% rename from src/test/compile-fail/trailing-carriage-return-in-string.rs rename to src/test/parse-fail/trailing-carriage-return-in-string.rs diff --git a/src/test/compile-fail/trailing-plus-in-bounds.rs b/src/test/parse-fail/trailing-plus-in-bounds.rs similarity index 100% rename from src/test/compile-fail/trailing-plus-in-bounds.rs rename to src/test/parse-fail/trailing-plus-in-bounds.rs diff --git a/src/test/compile-fail/trait-bounds-not-on-impl.rs b/src/test/parse-fail/trait-bounds-not-on-impl.rs similarity index 100% rename from src/test/compile-fail/trait-bounds-not-on-impl.rs rename to src/test/parse-fail/trait-bounds-not-on-impl.rs diff --git a/src/test/compile-fail/type-parameters-in-field-exprs.rs b/src/test/parse-fail/type-parameters-in-field-exprs.rs similarity index 100% rename from src/test/compile-fail/type-parameters-in-field-exprs.rs rename to src/test/parse-fail/type-parameters-in-field-exprs.rs diff --git a/src/test/compile-fail/unsized2.rs b/src/test/parse-fail/unsized2.rs similarity index 100% rename from src/test/compile-fail/unsized2.rs rename to src/test/parse-fail/unsized2.rs diff --git a/src/test/compile-fail/virtual-structs.rs b/src/test/parse-fail/virtual-structs.rs similarity index 100% rename from src/test/compile-fail/virtual-structs.rs rename to src/test/parse-fail/virtual-structs.rs diff --git a/src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs b/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs similarity index 100% rename from src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs rename to src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs From 6824f1365d2d1dc967c92bec11c44920bbf3da68 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 11 Feb 2015 23:09:30 +0100 Subject: [PATCH 02/76] Add pfail targets for parse-fail tests --- configure | 1 + mk/tests.mk | 17 +++++++++++++---- src/compiletest/common.rs | 3 +++ src/compiletest/compiletest.rs | 2 +- src/compiletest/runtest.rs | 5 +++-- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/configure b/configure index ec1e741fb9c5b..d1b27a96f93b9 100755 --- a/configure +++ b/configure @@ -1056,6 +1056,7 @@ do make_dir $h/test/run-pass-fulldeps make_dir $h/test/run-fail make_dir $h/test/compile-fail + make_dir $h/test/parse-fail make_dir $h/test/compile-fail-fulldeps make_dir $h/test/bench make_dir $h/test/perf diff --git a/mk/tests.mk b/mk/tests.mk index d8d77db1e0276..d907f2259a3af 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -173,12 +173,12 @@ check-notidy: cleantmptestlogs cleantestlibs all check-stage2 check-lite: cleantestlibs cleantmptestlogs \ $(foreach crate,$(TEST_TARGET_CRATES),check-stage2-$(crate)) \ check-stage2-rpass check-stage2-rpass-valgrind \ - check-stage2-rfail check-stage2-cfail check-stage2-rmake + check-stage2-rfail check-stage2-cfail check-stage2-pfail check-stage2-rmake $(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log # Only check the 'reference' tests: rpass/cfail/rfail/rmake. check-ref: cleantestlibs cleantmptestlogs check-stage2-rpass check-stage2-rpass-valgrind \ - check-stage2-rfail check-stage2-cfail check-stage2-rmake + check-stage2-rfail check-stage2-cfail check-stage2-pfail check-stage2-rmake $(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log # Only check the docs. @@ -290,6 +290,7 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \ check-stage$(1)-T-$(2)-H-$(3)-rpass-exec \ check-stage$(1)-T-$(2)-H-$(3)-rfail-exec \ check-stage$(1)-T-$(2)-H-$(3)-cfail-exec \ + check-stage$(1)-T-$(2)-H-$(3)-pfail-exec \ check-stage$(1)-T-$(2)-H-$(3)-rpass-valgrind-exec \ check-stage$(1)-T-$(2)-H-$(3)-rpass-full-exec \ check-stage$(1)-T-$(2)-H-$(3)-cfail-full-exec \ @@ -469,7 +470,8 @@ RPASS_VALGRIND_TESTS := $(RPASS_VALGRIND_RS) RPASS_FULL_TESTS := $(RPASS_FULL_RS) CFAIL_FULL_TESTS := $(CFAIL_FULL_RS) RFAIL_TESTS := $(RFAIL_RS) -CFAIL_TESTS := $(CFAIL_RS) $(PFAIL_RS) +CFAIL_TESTS := $(CFAIL_RS) +PFAIL_TESTS := $(PFAIL_RS) BENCH_TESTS := $(BENCH_RS) PERF_TESTS := $(PERF_RS) PRETTY_TESTS := $(PRETTY_RS) @@ -507,6 +509,11 @@ CTEST_BUILD_BASE_cfail = compile-fail CTEST_MODE_cfail = compile-fail CTEST_RUNTOOL_cfail = $(CTEST_RUNTOOL) +CTEST_SRC_BASE_pfail = parse-fail +CTEST_BUILD_BASE_pfail = parse-fail +CTEST_MODE_pfail = parse-fail +CTEST_RUNTOOL_pfail = $(CTEST_RUNTOOL) + CTEST_SRC_BASE_bench = bench CTEST_BUILD_BASE_bench = bench CTEST_MODE_bench = run-pass @@ -629,6 +636,7 @@ CTEST_DEPS_rpass-full_$(1)-T-$(2)-H-$(3) = $$(RPASS_FULL_TESTS) $$(CSREQ$(1)_T_$ CTEST_DEPS_cfail-full_$(1)-T-$(2)-H-$(3) = $$(CFAIL_FULL_TESTS) $$(CSREQ$(1)_T_$(3)_H_$(3)) $$(SREQ$(1)_T_$(2)_H_$(3)) CTEST_DEPS_rfail_$(1)-T-$(2)-H-$(3) = $$(RFAIL_TESTS) CTEST_DEPS_cfail_$(1)-T-$(2)-H-$(3) = $$(CFAIL_TESTS) +CTEST_DEPS_pfail_$(1)-T-$(2)-H-$(3) = $$(PFAIL_TESTS) CTEST_DEPS_bench_$(1)-T-$(2)-H-$(3) = $$(BENCH_TESTS) CTEST_DEPS_perf_$(1)-T-$(2)-H-$(3) = $$(PERF_TESTS) CTEST_DEPS_debuginfo-gdb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_GDB_TESTS) @@ -697,7 +705,7 @@ endif endef -CTEST_NAMES = rpass rpass-valgrind rpass-full cfail-full rfail cfail bench perf debuginfo-gdb debuginfo-lldb codegen +CTEST_NAMES = rpass rpass-valgrind rpass-full cfail-full rfail cfail pfail bench perf debuginfo-gdb debuginfo-lldb codegen $(foreach host,$(CFG_HOST), \ $(eval $(foreach target,$(CFG_TARGET), \ @@ -856,6 +864,7 @@ TEST_GROUPS = \ cfail-full \ rfail \ cfail \ + pfail \ bench \ perf \ rmake \ diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index df2981a6c8334..2c046d252799e 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -15,6 +15,7 @@ use std::str::FromStr; #[derive(Clone, Copy, PartialEq, Debug)] pub enum Mode { CompileFail, + ParseFail, RunFail, RunPass, RunPassValgrind, @@ -29,6 +30,7 @@ impl FromStr for Mode { fn from_str(s: &str) -> Result { match s { "compile-fail" => Ok(CompileFail), + "parse-fail" => Ok(ParseFail), "run-fail" => Ok(RunFail), "run-pass" => Ok(RunPass), "run-pass-valgrind" => Ok(RunPassValgrind), @@ -45,6 +47,7 @@ impl fmt::Display for Mode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(match *self { CompileFail => "compile-fail", + ParseFail => "parse-fail", RunFail => "run-fail", RunPass => "run-pass", RunPassValgrind => "run-pass-valgrind", diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 6b6251a96c944..72a57ee5bc24f 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -72,7 +72,7 @@ pub fn parse_config(args: Vec ) -> Config { reqopt("", "aux-base", "directory to find auxiliary test files", "PATH"), reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET"), reqopt("", "mode", "which sort of compile tests to run", - "(compile-fail|run-fail|run-pass|run-pass-valgrind|pretty|debug-info)"), + "(compile-fail|parse-fail|run-fail|run-pass|run-pass-valgrind|pretty|debug-info)"), optflag("", "ignored", "run tests marked as ignored"), optopt("", "runtool", "supervisor program to run tests under \ (eg. emulator, valgrind)", "PROGRAM"), diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 5a372fd7cdcb2..c5bb35ffe65e2 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -11,7 +11,7 @@ use self::TargetLocation::*; use common::Config; -use common::{CompileFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb}; +use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb}; use common::{Codegen, DebugInfoLldb}; use errors; use header::TestProps; @@ -66,6 +66,7 @@ pub fn run_metrics(config: Config, testfile: String, mm: &mut MetricMap) { debug!("loaded props"); match config.mode { CompileFail => run_cfail_test(&config, &props, &testfile), + ParseFail => run_cfail_test(&config, &props, &testfile), RunFail => run_rfail_test(&config, &props, &testfile), RunPass => run_rpass_test(&config, &props, &testfile), RunPassValgrind => run_valgrind_test(&config, &props, &testfile), @@ -88,7 +89,7 @@ fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) { let proc_res = compile_test(config, props, testfile); if proc_res.status.success() { - fatal_proc_rec("compile-fail test compiled successfully!", + fatal_proc_rec(&format!("{} test compiled successfully!", config.mode)[], &proc_res); } From 378abdbde790440fd61aece00d053ae400cab56d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 17 Feb 2015 10:40:46 +0100 Subject: [PATCH 03/76] Simplify the codegen in iter_vec_loop No need to create a bunch of blocks and a stack allocated temporary just to build a simple loop. --- src/librustc_trans/trans/tvec.rs | 51 +++++++++----------------------- 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index 8f10865ae32bc..d8ea5af8760c5 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -426,49 +426,26 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, let _icx = push_ctxt("tvec::iter_vec_loop"); let fcx = bcx.fcx; - let next_bcx = fcx.new_temp_block("expr_repeat: while next"); let loop_bcx = fcx.new_temp_block("expr_repeat"); - let cond_bcx = fcx.new_temp_block("expr_repeat: loop cond"); - let body_bcx = fcx.new_temp_block("expr_repeat: body: set"); - let inc_bcx = fcx.new_temp_block("expr_repeat: body: inc"); - Br(bcx, loop_bcx.llbb, DebugLoc::None); + let next_bcx = fcx.new_temp_block("expr_repeat: next"); - let loop_counter = { - // i = 0 - let i = alloca(loop_bcx, bcx.ccx().int_type(), "__i"); - Store(loop_bcx, C_uint(bcx.ccx(), 0us), i); + Br(bcx, loop_bcx.llbb, DebugLoc::None); - Br(loop_bcx, cond_bcx.llbb, DebugLoc::None); - i - }; + let loop_counter = Phi(loop_bcx, bcx.ccx().int_type(), &[C_uint(bcx.ccx(), 0us)], &[bcx.llbb]); - { // i < count - let lhs = Load(cond_bcx, loop_counter); - let rhs = count; - let cond_val = ICmp(cond_bcx, llvm::IntULT, lhs, rhs, DebugLoc::None); + let bcx = loop_bcx; - CondBr(cond_bcx, cond_val, body_bcx.llbb, next_bcx.llbb, DebugLoc::None); - } - - { // loop body - let i = Load(body_bcx, loop_counter); - let lleltptr = if vt.llunit_alloc_size == 0 { - data_ptr - } else { - InBoundsGEP(body_bcx, data_ptr, &[i]) - }; - let body_bcx = f(body_bcx, lleltptr, vt.unit_ty); - - Br(body_bcx, inc_bcx.llbb, DebugLoc::None); - } - - { // i += 1 - let i = Load(inc_bcx, loop_counter); - let plusone = Add(inc_bcx, i, C_uint(bcx.ccx(), 1us), DebugLoc::None); - Store(inc_bcx, plusone, loop_counter); + let lleltptr = if vt.llunit_alloc_size == 0 { + data_ptr + } else { + InBoundsGEP(bcx, data_ptr, &[loop_counter]) + }; + let bcx = f(bcx, lleltptr, vt.unit_ty); + let plusone = Add(bcx, loop_counter, C_uint(bcx.ccx(), 1us), DebugLoc::None); + AddIncomingToPhi(loop_counter, plusone, bcx.llbb); - Br(inc_bcx, cond_bcx.llbb, DebugLoc::None); - } + let cond_val = ICmp(bcx, llvm::IntULT, plusone, count, DebugLoc::None); + CondBr(bcx, cond_val, loop_bcx.llbb, next_bcx.llbb, DebugLoc::None); next_bcx } From 0fe880bdb788032100b9cd1633770b56393784f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 17 Feb 2015 10:43:27 +0100 Subject: [PATCH 04/76] Use the right array type in trans_slice_vec In trans_slice_vec we currently use arrayalloca, which gives us a pointer to the element type with enough memory allocated for the requested number of elements. This works, but everywhere else we use the [n x T] type for fixed size arrays and so we have to bitcast the pointer here. Let's directly use the proper type for the allocation and remove some code duplication along the way. --- src/librustc_trans/trans/base.rs | 13 ------------- src/librustc_trans/trans/tvec.rs | 28 +++++++++++----------------- 2 files changed, 11 insertions(+), 30 deletions(-) diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 7f7b5cd800660..971d73aa899b6 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -1219,19 +1219,6 @@ pub fn alloca_zeroed<'blk, 'tcx>(cx: Block<'blk, 'tcx>, ty: Ty<'tcx>, p } -pub fn arrayalloca(cx: Block, ty: Type, v: ValueRef) -> ValueRef { - let _icx = push_ctxt("arrayalloca"); - if cx.unreachable.get() { - unsafe { - return llvm::LLVMGetUndef(ty.to_ref()); - } - } - debuginfo::clear_source_location(cx.fcx); - let p = ArrayAlloca(cx, ty, v); - call_lifetime_start(cx, p); - p -} - // Creates the alloca slot which holds the pointer to the slot for the final return value pub fn make_return_slot_pointer<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>, output_type: Ty<'tcx>) -> ValueRef { diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index 8f10865ae32bc..bf94a2e23daf2 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -171,33 +171,27 @@ pub fn trans_slice_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let vt = vec_types_from_expr(bcx, content_expr); let count = elements_required(bcx, content_expr); debug!(" vt={}, count={}", vt.to_string(ccx), count); - let llcount = C_uint(ccx, count); let fixed_ty = ty::mk_vec(bcx.tcx(), vt.unit_ty, Some(count)); - let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty).ptr_to(); + let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty); - let llfixed = if count == 0 { - // Just create a zero-sized alloca to preserve - // the non-null invariant of the inner slice ptr - let llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount); - BitCast(bcx, llfixed, llfixed_ty) - } else { - // Make a fixed-length backing array and allocate it on the stack. - let llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount); + // Always create an alloca even if zero-sized, to preserve + // the non-null invariant of the inner slice ptr + let llfixed = base::alloca(bcx, llfixed_ty, ""); + if count > 0 { // Arrange for the backing array to be cleaned up. - let llfixed_casted = BitCast(bcx, llfixed, llfixed_ty); let cleanup_scope = cleanup::temporary_scope(bcx.tcx(), content_expr.id); - fcx.schedule_lifetime_end(cleanup_scope, llfixed_casted); - fcx.schedule_drop_mem(cleanup_scope, llfixed_casted, fixed_ty); + fcx.schedule_lifetime_end(cleanup_scope, llfixed); + fcx.schedule_drop_mem(cleanup_scope, llfixed, fixed_ty); // Generate the content into the backing array. - bcx = write_content(bcx, &vt, slice_expr, - content_expr, SaveIn(llfixed)); - - llfixed_casted + // llfixed has type *[T x N], but we want the type *T, + // so use GEP to convert + bcx = write_content(bcx, &vt, slice_expr, content_expr, + SaveIn(GEPi(bcx, llfixed, &[0, 0]))); }; immediate_rvalue_bcx(bcx, llfixed, vec_ty).to_expr_datumblock() From 02e1d5ec0613c0c6e89e4cd55376b112c57a582c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 17 Feb 2015 10:56:26 -0500 Subject: [PATCH 05/76] When converting parameters for an object type, be careful of defaults that reference `Self`. Fixes #18956. --- src/librustc/util/ppaux.rs | 15 ++++++++++- src/librustc_typeck/astconv.rs | 23 ++++++++++++---- ...rameter-defaults-referencing-Self-ppaux.rs | 26 +++++++++++++++++++ ...ype-parameter-defaults-referencing-Self.rs | 23 ++++++++++++++++ 4 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs create mode 100644 src/test/compile-fail/type-parameter-defaults-referencing-Self.rs diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 0363978bada25..cb928ce64bc5c 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -508,13 +508,26 @@ pub fn parameterized<'tcx,GG>(cx: &ctxt<'tcx>, // avoid those ICEs. let generics = get_generics(); + let has_self = substs.self_ty().is_some(); let tps = substs.types.get_slice(subst::TypeSpace); let ty_params = generics.types.get_slice(subst::TypeSpace); let has_defaults = ty_params.last().map_or(false, |def| def.default.is_some()); let num_defaults = if has_defaults { ty_params.iter().zip(tps.iter()).rev().take_while(|&(def, &actual)| { match def.default { - Some(default) => default.subst(cx, substs) == actual, + Some(default) => { + if !has_self && ty::type_has_self(default) { + // In an object type, there is no `Self`, and + // thus if the default value references Self, + // the user will be required to give an + // explicit value. We can't even do the + // substitution below to check without causing + // an ICE. (#18956). + false + } else { + default.subst(cx, substs) == actual + } + } None => false } }).count() diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 0183b3474a509..19cf3bb93ea17 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -404,17 +404,30 @@ fn create_substs_for_ast_path<'tcx>( let actual_supplied_ty_param_count = substs.types.len(TypeSpace); for param in &ty_param_defs[actual_supplied_ty_param_count..] { - match param.default { - Some(default) => { + if let Some(default) = param.default { + // If we are converting an object type, then the + // `Self` parameter is unknown. However, some of the + // other type parameters may reference `Self` in their + // defaults. This will lead to an ICE if we are not + // careful! + if self_ty.is_none() && ty::type_has_self(default) { + tcx.sess.span_err( + span, + &format!("the type parameter `{}` must be explicitly specified \ + in an object type because its default value `{}` references \ + the type `Self`", + param.name.user_string(tcx), + default.user_string(tcx))); + substs.types.push(TypeSpace, tcx.types.err); + } else { // This is a default type parameter. let default = default.subst_spanned(tcx, &substs, Some(span)); substs.types.push(TypeSpace, default); } - None => { - tcx.sess.span_bug(span, "extra parameter without default"); - } + } else { + tcx.sess.span_bug(span, "extra parameter without default"); } } diff --git a/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs b/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs new file mode 100644 index 0000000000000..8ff514e04e360 --- /dev/null +++ b/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs @@ -0,0 +1,26 @@ +// Copyright 2015 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. + +// Test a default that references `Self` which is then used in an +// object type. Issue #18956. In this case, the value is supplied by +// the user, but pretty-printing the type during the error message +// caused an ICE. + +trait MyAdd { fn add(&self, other: &Rhs) -> Self; } + +impl MyAdd for i32 { + fn add(&self, other: &i32) -> i32 { *self + *other } +} + +fn main() { + let x = 5; + let y = x as MyAdd; + //~^ ERROR as `MyAdd` +} diff --git a/src/test/compile-fail/type-parameter-defaults-referencing-Self.rs b/src/test/compile-fail/type-parameter-defaults-referencing-Self.rs new file mode 100644 index 0000000000000..9982d4850248b --- /dev/null +++ b/src/test/compile-fail/type-parameter-defaults-referencing-Self.rs @@ -0,0 +1,23 @@ +// Copyright 2015 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. + +// Test a default that references `Self` which is then used in an object type. +// Issue #18956. + +#![feature(default_type_params)] + +trait Foo { + fn method(&self); +} + +fn foo(x: &Foo) { } +//~^ ERROR the type parameter `T` must be explicitly specified + +fn main() { } From ff388c12770dd8aa33ed48595f780d2aa49cd5d2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 17 Feb 2015 10:57:15 -0500 Subject: [PATCH 06/76] Traits that reference `Self` in the supertrait list are not object-safe. Fixes #22040. --- src/librustc/middle/traits/object_safety.rs | 52 ++++++++++++++++--- src/librustc/middle/ty.rs | 36 ++++++++++++- src/librustc_typeck/check/vtable.rs | 7 +++ .../compile-fail/object-safety-issue-22040.rs | 50 ++++++++++++++++++ .../object-safety-supertrait-mentions-Self.rs | 32 ++++++++++++ 5 files changed, 170 insertions(+), 7 deletions(-) create mode 100644 src/test/compile-fail/object-safety-issue-22040.rs create mode 100644 src/test/compile-fail/object-safety-supertrait-mentions-Self.rs diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs index b2701ae875c0c..d8d75f9084b6b 100644 --- a/src/librustc/middle/traits/object_safety.rs +++ b/src/librustc/middle/traits/object_safety.rs @@ -20,7 +20,7 @@ use super::supertraits; use super::elaborate_predicates; -use middle::subst::{self, SelfSpace}; +use middle::subst::{self, SelfSpace, TypeSpace}; use middle::traits; use middle::ty::{self, Ty}; use std::rc::Rc; @@ -31,6 +31,10 @@ pub enum ObjectSafetyViolation<'tcx> { /// Self : Sized declared on the trait SizedSelf, + /// Supertrait reference references `Self` an in illegal location + /// (e.g. `trait Foo : Bar`) + SupertraitSelf, + /// Method has something illegal Method(Rc>, MethodViolationCode), } @@ -110,6 +114,9 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>, if trait_has_sized_self(tcx, trait_def_id) { violations.push(ObjectSafetyViolation::SizedSelf); } + if supertraits_reference_self(tcx, trait_def_id) { + violations.push(ObjectSafetyViolation::SupertraitSelf); + } debug!("object_safety_violations_for_trait(trait_def_id={}) = {}", trait_def_id.repr(tcx), @@ -118,6 +125,34 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>, violations } +fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>, + trait_def_id: ast::DefId) + -> bool +{ + let trait_def = ty::lookup_trait_def(tcx, trait_def_id); + let trait_ref = trait_def.trait_ref.clone(); + let predicates = ty::predicates_for_trait_ref(tcx, &ty::Binder(trait_ref)); + predicates + .into_iter() + .any(|predicate| { + match predicate { + ty::Predicate::Trait(ref data) => { + // In the case of a trait predicate, we can skip the "self" type. + data.0.trait_ref.substs.types.get_slice(TypeSpace) + .iter() + .cloned() + .any(is_self) + } + ty::Predicate::Projection(..) | + ty::Predicate::TypeOutlives(..) | + ty::Predicate::RegionOutlives(..) | + ty::Predicate::Equate(..) => { + false + } + } + }) +} + fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>, trait_def_id: ast::DefId) -> bool @@ -138,11 +173,7 @@ fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>, .any(|predicate| { match predicate { ty::Predicate::Trait(ref trait_pred) if trait_pred.def_id() == sized_def_id => { - let self_ty = trait_pred.0.self_ty(); - match self_ty.sty { - ty::ty_param(ref data) => data.space == subst::SelfSpace, - _ => false, - } + is_self(trait_pred.0.self_ty()) } ty::Predicate::Projection(..) | ty::Predicate::Trait(..) | @@ -295,8 +326,17 @@ impl<'tcx> Repr<'tcx> for ObjectSafetyViolation<'tcx> { match *self { ObjectSafetyViolation::SizedSelf => format!("SizedSelf"), + ObjectSafetyViolation::SupertraitSelf => + format!("SupertraitSelf"), ObjectSafetyViolation::Method(ref m, code) => format!("Method({},{:?})", m.repr(tcx), code), } } } + +fn is_self<'tcx>(ty: Ty<'tcx>) -> bool { + match ty.sty { + ty::ty_param(ref data) => data.space == subst::SelfSpace, + _ => false, + } +} diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 107715a826157..02eeed1cfda89 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -78,7 +78,7 @@ use std::marker; use std::mem; use std::ops; use std::rc::Rc; -use std::vec::CowVec; +use std::vec::{CowVec, IntoIter}; use collections::enum_set::{EnumSet, CLike}; use std::collections::{HashMap, HashSet}; use syntax::abi; @@ -2034,6 +2034,40 @@ impl<'tcx> AsPredicate<'tcx> for PolyProjectionPredicate<'tcx> { } impl<'tcx> Predicate<'tcx> { + /// Iterates over the types in this predicate. Note that in all + /// cases this is skipping over a binder, so late-bound regions + /// with depth 0 are bound by the predicate. + pub fn walk_tys(&self) -> IntoIter> { + let vec: Vec<_> = match *self { + ty::Predicate::Trait(ref data) => { + data.0.trait_ref.substs.types.as_slice().to_vec() + } + ty::Predicate::Equate(ty::Binder(ref data)) => { + vec![data.0, data.1] + } + ty::Predicate::TypeOutlives(ty::Binder(ref data)) => { + vec![data.0] + } + ty::Predicate::RegionOutlives(..) => { + vec![] + } + ty::Predicate::Projection(ref data) => { + let trait_inputs = data.0.projection_ty.trait_ref.substs.types.as_slice(); + trait_inputs.iter() + .cloned() + .chain(Some(data.0.ty).into_iter()) + .collect() + } + }; + + // The only reason to collect into a vector here is that I was + // too lazy to make the full (somewhat complicated) iterator + // type that would be needed here. But I wanted this fn to + // return an iterator conceptually, rather than a `Vec`, so as + // to be closer to `Ty::walk`. + vec.into_iter() + } + pub fn has_escaping_regions(&self) -> bool { match *self { Predicate::Trait(ref trait_ref) => trait_ref.has_escaping_regions(), diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index 2e7eff68bd509..3666b69d1c678 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -126,6 +126,13 @@ pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>, "the trait cannot require that `Self : Sized`"); } + ObjectSafetyViolation::SupertraitSelf => { + tcx.sess.span_note( + span, + "the trait cannot use `Self` as a type parameter \ + in the supertrait listing"); + } + ObjectSafetyViolation::Method(method, MethodViolationCode::ByValueSelf) => { tcx.sess.span_note( span, diff --git a/src/test/compile-fail/object-safety-issue-22040.rs b/src/test/compile-fail/object-safety-issue-22040.rs new file mode 100644 index 0000000000000..edf32131b6875 --- /dev/null +++ b/src/test/compile-fail/object-safety-issue-22040.rs @@ -0,0 +1,50 @@ +// Copyright 2015 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. + +// Regression test for #22040. + +use std::fmt::Debug; + +trait Expr: Debug + PartialEq { + fn print_element_count(&self); +} + +//#[derive(PartialEq)] +#[derive(Debug)] +struct SExpr<'x> { + elements: Vec>, +} + +impl<'x> PartialEq for SExpr<'x> { + fn eq(&self, other:&SExpr<'x>) -> bool { + println!("L1: {} L2: {}", self.elements.len(), other.elements.len()); + let result = self.elements.len() == other.elements.len(); + + println!("Got compare {}", result); + return result; + } +} + +impl <'x> SExpr<'x> { + fn new() -> SExpr<'x> { return SExpr{elements: Vec::new(),}; } +} + +impl <'x> Expr for SExpr<'x> { + fn print_element_count(&self) { + println!("element count: {}", self.elements.len()); + } +} + +fn main() { + let a: Box = Box::new(SExpr::new()); //~ ERROR trait `Expr` is not object-safe + let b: Box = Box::new(SExpr::new()); //~ ERROR trait `Expr` is not object-safe + + assert_eq!(a , b); +} diff --git a/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs b/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs new file mode 100644 index 0000000000000..d3f9dc73020fb --- /dev/null +++ b/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs @@ -0,0 +1,32 @@ +// Copyright 2014 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. + +// Check that we correctly prevent users from making trait objects +// form traits that make use of `Self` in an argument or return position. + +trait Bar { + fn bar(&self, x: &T); +} + +trait Baz : Bar { +} + +fn make_bar>(t: &T) -> &Bar { + t +} + +fn make_baz(t: &T) -> &Baz { + t + //~^ ERROR `Baz` is not object-safe + //~| NOTE the trait cannot use `Self` as a type parameter in the supertrait listing +} + +fn main() { +} From 5705d48e280f8a0065c214edfb3dcdcecc323316 Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Fri, 13 Feb 2015 17:27:43 +0000 Subject: [PATCH 07/76] Implement RandomAccessIterator for Cloned --- src/libcore/iter.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 03c473ed96741..299864e3b3d7d 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1323,6 +1323,23 @@ impl ExactSizeIterator for Cloned where I: ExactSizeIterator, {} +#[unstable(feature = "core", reason = "trait is experimental")] +impl RandomAccessIterator for Cloned where + T: Clone, + D: Deref, + I: RandomAccessIterator +{ + #[inline] + fn indexable(&self) -> usize { + self.it.indexable() + } + + #[inline] + fn idx(&mut self, index: usize) -> Option { + self.it.idx(index).cloned() + } +} + /// An iterator that repeats endlessly #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] From 2f586b9687e5c33d9d3b8eccfc309f65d2a9f4e9 Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Fri, 13 Feb 2015 07:33:44 +0000 Subject: [PATCH 08/76] Opt for .cloned() over .map(|x| x.clone()) etc. --- src/compiletest/compiletest.rs | 1 + src/compiletest/runtest.rs | 2 +- src/libcollections/bit.rs | 6 +++--- src/libcollections/dlist.rs | 4 ++-- src/libcore/iter.rs | 2 +- src/libcoretest/iter.rs | 2 +- src/librustc/metadata/cstore.rs | 5 ++--- src/librustc/middle/check_match.rs | 2 +- src/librustc/middle/const_eval.rs | 2 +- src/librustc/middle/dependency_format.rs | 2 +- src/librustc/middle/infer/error_reporting.rs | 2 +- src/librustc/middle/lang_items.rs | 16 +++++----------- src/librustc/middle/region.rs | 2 +- src/librustc/middle/resolve_lifetime.rs | 2 +- src/librustc/middle/traits/select.rs | 2 +- src/librustc/middle/ty.rs | 6 +++--- src/librustc/util/common.rs | 2 +- src/librustc_back/rpath.rs | 5 +---- src/librustc_driver/test.rs | 2 +- src/librustc_resolve/lib.rs | 15 ++++++--------- src/librustc_trans/trans/base.rs | 2 +- src/librustc_trans/trans/expr.rs | 2 +- src/librustc_trans/trans/type_of.rs | 2 +- src/librustc_typeck/check/mod.rs | 4 ++-- src/librustdoc/passes.rs | 2 +- src/librustdoc/visit_ast.rs | 2 +- src/libstd/env.rs | 8 ++++---- src/libsyntax/ast_map/mod.rs | 2 +- src/libsyntax/diagnostics/registry.rs | 2 +- src/libsyntax/ext/base.rs | 2 +- src/libsyntax/ext/deriving/generic/mod.rs | 10 +++++----- src/libsyntax/ext/source_util.rs | 2 +- src/libsyntax/ext/tt/macro_parser.rs | 2 +- src/libsyntax/ext/tt/macro_rules.rs | 2 +- src/libsyntax/parse/lexer/comments.rs | 4 ++-- src/libsyntax/parse/parser.rs | 9 ++++----- src/libsyntax/print/pprust.rs | 7 +++---- src/test/bench/shootout-fasta.rs | 2 +- src/test/bench/shootout-meteor.rs | 2 +- 39 files changed, 68 insertions(+), 82 deletions(-) diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 6c1308a01c4a1..0cfaaae2009c9 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -21,6 +21,7 @@ #![feature(test)] #![feature(unicode)] #![feature(env)] +#![feature(core)] #![deny(warnings)] diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 54c011832d1dc..8da11a9a50d44 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -1133,7 +1133,7 @@ fn compile_test_(config: &Config, props: &TestProps, // FIXME (#9639): This needs to handle non-utf8 paths let mut link_args = vec!("-L".to_string(), aux_dir.as_str().unwrap().to_string()); - link_args.extend(extra_args.iter().map(|s| s.clone())); + link_args.extend(extra_args.iter().cloned()); let args = make_compile_args(config, props, link_args, diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index ca598a8d4d292..d6e5b3fe464a6 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -2306,7 +2306,7 @@ mod tests { #[test] fn test_from_bools() { let bools = vec![true, false, true, true]; - let bitv: Bitv = bools.iter().map(|n| *n).collect(); + let bitv: Bitv = bools.iter().cloned().collect(); assert_eq!(format!("{:?}", bitv), "1011"); } @@ -2319,12 +2319,12 @@ mod tests { #[test] fn test_bitv_iterator() { let bools = vec![true, false, true, true]; - let bitv: Bitv = bools.iter().map(|n| *n).collect(); + let bitv: Bitv = bools.iter().cloned().collect(); assert_eq!(bitv.iter().collect::>(), bools); let long: Vec<_> = (0i32..10000).map(|i| i % 2 == 0).collect(); - let bitv: Bitv = long.iter().map(|n| *n).collect(); + let bitv: Bitv = long.iter().cloned().collect(); assert_eq!(bitv.iter().collect::>(), long) } diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 27b282ee9a9c1..4da6f96300679 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -938,7 +938,7 @@ impl Ord for DList { #[stable(feature = "rust1", since = "1.0.0")] impl Clone for DList { fn clone(&self) -> DList { - self.iter().map(|x| x.clone()).collect() + self.iter().cloned().collect() } } @@ -1056,7 +1056,7 @@ mod tests { #[cfg(test)] fn list_from(v: &[T]) -> DList { - v.iter().map(|x| (*x).clone()).collect() + v.iter().cloned().collect() } #[test] diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 299864e3b3d7d..c5e0966720fd2 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -350,7 +350,7 @@ pub trait IteratorExt: Iterator + Sized { /// /// ``` /// let xs = [100, 200, 300]; - /// let mut it = xs.iter().map(|x| *x).peekable(); + /// let mut it = xs.iter().cloned().peekable(); /// assert_eq!(*it.peek().unwrap(), 100); /// assert_eq!(it.next().unwrap(), 100); /// assert_eq!(it.next().unwrap(), 200); diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 7eb0fb97bed2a..88777da0bcd35 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -713,7 +713,7 @@ fn test_random_access_inspect() { fn test_random_access_map() { let xs = [1, 2, 3, 4, 5]; - let mut it = xs.iter().map(|x| *x); + let mut it = xs.iter().cloned(); assert_eq!(xs.len(), it.indexable()); for (i, elt) in xs.iter().enumerate() { assert_eq!(Some(*elt), it.idx(i)); diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 0a3e173b35ee5..a3f7d57da6748 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -139,8 +139,7 @@ impl CStore { pub fn get_used_crate_source(&self, cnum: ast::CrateNum) -> Option { self.used_crate_sources.borrow_mut() - .iter().find(|source| source.cnum == cnum) - .map(|source| source.clone()) + .iter().find(|source| source.cnum == cnum).cloned() } pub fn reset(&self) { @@ -218,7 +217,7 @@ impl CStore { pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option { - self.extern_mod_crate_map.borrow().get(&emod_id).map(|x| *x) + self.extern_mod_crate_map.borrow().get(&emod_id).cloned() } } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 03456f8529028..4544f283e1cc2 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -76,7 +76,7 @@ impl<'a> fmt::Debug for Matrix<'a> { pretty_printed_matrix.iter().map(|row| row[col].len()).max().unwrap_or(0) }).collect(); - let total_width = column_widths.iter().map(|n| *n).sum() + column_count * 3 + 1; + let total_width = column_widths.iter().cloned().sum() + column_count * 3 + 1; let br = repeat('+').take(total_width).collect::(); try!(write!(f, "{}\n", br)); for row in pretty_printed_matrix { diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 3d03cd946c48f..456d4a3a86e39 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -501,7 +501,7 @@ fn lit_to_const(lit: &ast::Lit, ty_hint: Option) -> const_val { match lit.node { ast::LitStr(ref s, _) => const_str((*s).clone()), ast::LitBinary(ref data) => { - const_binary(Rc::new(data.iter().map(|x| *x).collect())) + const_binary(data.clone()) } ast::LitByte(n) => const_uint(n as u64), ast::LitChar(n) => const_uint(n as u64), diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 6d35a82d153cd..ad9f4eade5c90 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -158,7 +158,7 @@ fn calculate_type(sess: &session::Session, // Collect what we've got so far in the return vector. let mut ret = (1..sess.cstore.next_crate_num()).map(|i| { - match formats.get(&i).map(|v| *v) { + match formats.get(&i).cloned() { v @ Some(cstore::RequireDynamic) => v, _ => None, } diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 72b33613c66aa..49bd2e67a1918 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -924,7 +924,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { fn rebuild(&self) -> (ast::FnDecl, Option, ast::Generics) { - let mut expl_self_opt = self.expl_self_opt.map(|x| x.clone()); + let mut expl_self_opt = self.expl_self_opt.cloned(); let mut inputs = self.fn_decl.inputs.clone(); let mut output = self.fn_decl.output.clone(); let mut ty_params = self.generics.ty_params.clone(); diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index e13a5672778e2..ce8f0d87e564c 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -147,18 +147,12 @@ struct LanguageItemCollector<'a> { impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> { fn visit_item(&mut self, item: &ast::Item) { - match extract(&item.attrs) { - Some(value) => { - let item_index = self.item_refs.get(&value[]).map(|x| *x); - - match item_index { - Some(item_index) => { - self.collect_item(item_index, local_def(item.id), item.span) - } - None => {} - } + if let Some(value) = extract(&item.attrs) { + let item_index = self.item_refs.get(&value[]).cloned(); + + if let Some(item_index) = item_index { + self.collect_item(item_index, local_def(item.id), item.span) } - None => {} } visit::walk_item(self, item); diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 2f0462ab8c338..e539f6ae6cb93 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -407,7 +407,7 @@ impl RegionMaps { pub fn opt_encl_scope(&self, id: CodeExtent) -> Option { //! Returns the narrowest scope that encloses `id`, if any. - self.scope_map.borrow().get(&id).map(|x| *x) + self.scope_map.borrow().get(&id).cloned() } #[allow(dead_code)] // used in middle::cfg diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index e91d7d8c52cde..3ba08c1032031 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -562,7 +562,7 @@ pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec SelectionContext<'cx, 'tcx> { { let cache = self.pick_candidate_cache(); let hashmap = cache.hashmap.borrow(); - hashmap.get(&cache_fresh_trait_pred.0.trait_ref).map(|c| (*c).clone()) + hashmap.get(&cache_fresh_trait_pred.0.trait_ref).cloned() } fn insert_candidate_cache(&mut self, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 107715a826157..8ca54cce8e363 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2868,7 +2868,7 @@ pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>, def_id: ast::DefId, input_tys: &[Ty<'tcx>], output: Ty<'tcx>) -> Ty<'tcx> { - let input_args = input_tys.iter().map(|ty| *ty).collect(); + let input_args = input_tys.iter().cloned().collect(); mk_bare_fn(cx, Some(def_id), cx.mk_bare_fn(BareFnTy { @@ -3837,7 +3837,7 @@ pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>) -> Representability { match ty.sty { ty_tup(ref ts) => { - find_nonrepresentable(cx, sp, seen, ts.iter().map(|ty| *ty)) + find_nonrepresentable(cx, sp, seen, ts.iter().cloned()) } // Fixed-length vectors. // FIXME(#11924) Behavior undecided for zero-length vectors. @@ -4965,7 +4965,7 @@ pub fn note_and_explain_type_err(cx: &ctxt, err: &type_err) { } pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option { - cx.provided_method_sources.borrow().get(&id).map(|x| *x) + cx.provided_method_sources.borrow().get(&id).cloned() } pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index d3d0f56c3ce90..a6d8bc24da76f 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -214,7 +214,7 @@ pub fn memoized(cache: &RefCell>, arg: T, f: F) -> F: FnOnce(T) -> U, { let key = arg.clone(); - let result = cache.borrow().get(&key).map(|result| result.clone()); + let result = cache.borrow().get(&key).cloned(); match result { Some(result) => result, None => { diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs index 36bbd4b987297..3de69bd72e1e4 100644 --- a/src/librustc_back/rpath.rs +++ b/src/librustc_back/rpath.rs @@ -40,10 +40,7 @@ pub fn get_rpath_flags(config: RPathConfig) -> Vec where debug!("preparing the RPATH!"); let libs = config.used_crates.clone(); - let libs = libs.into_iter().filter_map(|(_, l)| { - l.map(|p| p.clone()) - }).collect::>(); - + let libs = libs.into_iter().filter_map(|(_, l)| l).collect::>(); let rpaths = get_rpaths(config, &libs[]); flags.push_all(&rpaths_to_flags(&rpaths[])[]); flags diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 7105a6cc48882..e614f87c98099 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -254,7 +254,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> { output_ty: Ty<'tcx>) -> Ty<'tcx> { - let input_args = input_tys.iter().map(|ty| *ty).collect(); + let input_args = input_tys.iter().cloned().collect(); ty::mk_bare_fn(self.infcx.tcx, None, self.infcx.tcx.mk_bare_fn(ty::BareFnTy { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 874c8f2a9402d..337ba77fe7fbb 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1920,18 +1920,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { -> ResolveResult<(Rc, LastPrivate)> { fn search_parent_externals(needle: Name, module: &Rc) -> Option> { - module.external_module_children.borrow() - .get(&needle).cloned() - .map(|_| module.clone()) - .or_else(|| { - match module.parent_link.clone() { - ModuleParentLink(parent, _) => { - search_parent_externals(needle, - &parent.upgrade().unwrap()) + match module.external_module_children.borrow().get(&needle) { + Some(_) => Some(module.clone()), + None => match module.parent_link { + ModuleParentLink(ref parent, _) => { + search_parent_externals(needle, &parent.upgrade().unwrap()) } _ => None } - }) + } } let mut search_module = module_; diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 7f7b5cd800660..62d4dbeb0ad0c 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -3211,7 +3211,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>) reachable.push("rust_eh_personality_catch".to_string()); if codegen_units > 1 { - internalize_symbols(&shared_ccx, &reachable.iter().map(|x| x.clone()).collect()); + internalize_symbols(&shared_ccx, &reachable.iter().cloned().collect()); } let metadata_module = ModuleTranslation { diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 480679f43cb76..306d0f610c657 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -1197,7 +1197,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let trait_ref = bcx.tcx().object_cast_map.borrow() .get(&expr.id) - .map(|t| (*t).clone()) + .cloned() .unwrap(); let trait_ref = bcx.monomorphize(&trait_ref); let datum = unpack_datum!(bcx, trans(bcx, &**val)); diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 9d1c0fadefcd2..546c62e5dd247 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -67,7 +67,7 @@ pub fn untuple_arguments_if_necessary<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, abi: abi::Abi) -> Vec> { if abi != abi::RustCall { - return inputs.iter().map(|x| (*x).clone()).collect() + return inputs.iter().cloned().collect() } if inputs.len() == 0 { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 30896c1607a88..1ba2e38201c63 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3220,7 +3220,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, for field in ast_fields { let mut expected_field_type = tcx.types.err; - let pair = class_field_map.get(&field.ident.node.name).map(|x| *x); + let pair = class_field_map.get(&field.ident.node.name).cloned(); match pair { None => { fcx.type_error_message( @@ -3852,7 +3852,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } ast::ExprStruct(ref path, ref fields, ref base_expr) => { // Resolve the path. - let def = tcx.def_map.borrow().get(&id).map(|i| *i); + let def = tcx.def_map.borrow().get(&id).cloned(); let struct_id = match def { Some(def::DefVariant(enum_id, variant_id, true)) => { check_struct_enum_variant(fcx, id, expr.span, enum_id, diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs index abd73fcfb7028..722f14fa6d4c7 100644 --- a/src/librustdoc/passes.rs +++ b/src/librustdoc/passes.rs @@ -293,7 +293,7 @@ pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult { let mut a: Vec = i.attrs.iter().filter(|&a| match a { &clean::NameValue(ref x, _) if "doc" == *x => false, _ => true - }).map(|x| x.clone()).collect(); + }).cloned().collect(); if docstr.len() > 0 { a.push(clean::NameValue("doc".to_string(), docstr)); } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index ac1a02854124a..c52b0bab1fa8b 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -333,7 +333,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { name: name, items: items.clone(), generics: gen.clone(), - bounds: b.iter().map(|x| (*x).clone()).collect(), + bounds: b.iter().cloned().collect(), id: item.id, attrs: item.attrs.clone(), whence: item.span, diff --git a/src/libstd/env.rs b/src/libstd/env.rs index ea18838211f26..bfc1afc6eb4f2 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -918,7 +918,7 @@ mod tests { #[cfg(unix)] fn join_paths_unix() { fn test_eq(input: &[&str], output: &str) -> bool { - &*join_paths(input.iter().map(|s| *s)).unwrap() == + &*join_paths(input.iter().cloned()).unwrap() == OsStr::from_str(output) } @@ -927,14 +927,14 @@ mod tests { "/bin:/usr/bin:/usr/local/bin")); assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:")); - assert!(join_paths(["/te:st"].iter().map(|s| *s)).is_err()); + assert!(join_paths(["/te:st"].iter().cloned()).is_err()); } #[test] #[cfg(windows)] fn join_paths_windows() { fn test_eq(input: &[&str], output: &str) -> bool { - &*join_paths(input.iter().map(|s| *s)).unwrap() == + &*join_paths(input.iter().cloned()).unwrap() == OsStr::from_str(output) } @@ -945,6 +945,6 @@ mod tests { r";c:\windows;;;c:\;")); assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#)); - assert!(join_paths([r#"c:\te"st"#].iter().map(|s| *s)).is_err()); + assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err()); } } diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index 5535e5911e0c2..6535705388d01 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -251,7 +251,7 @@ impl<'ast> Map<'ast> { } fn find_entry(&self, id: NodeId) -> Option> { - self.map.borrow().get(id as usize).map(|e| *e) + self.map.borrow().get(id as usize).cloned() } pub fn krate(&self) -> &'ast Crate { diff --git a/src/libsyntax/diagnostics/registry.rs b/src/libsyntax/diagnostics/registry.rs index 62d48189c4347..968fceb6f6fd0 100644 --- a/src/libsyntax/diagnostics/registry.rs +++ b/src/libsyntax/diagnostics/registry.rs @@ -21,6 +21,6 @@ impl Registry { } pub fn find_description(&self, code: &str) -> Option<&'static str> { - self.descriptions.get(code).map(|desc| *desc) + self.descriptions.get(code).cloned() } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 083039995ee95..8fdc3c8447a32 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -639,7 +639,7 @@ impl<'a> ExtCtxt<'a> { pub fn mod_path(&self) -> Vec { let mut v = Vec::new(); v.push(token::str_to_ident(&self.ecfg.crate_name[])); - v.extend(self.mod_path.iter().map(|a| *a)); + v.extend(self.mod_path.iter().cloned()); return v; } pub fn bt_push(&mut self, ei: ExpnInfo) { diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index f878cb5ca8b78..8b4eaab386d00 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -367,7 +367,7 @@ impl<'a> TraitDef<'a> { "allow" | "warn" | "deny" | "forbid" => true, _ => false, } - }).map(|a| a.clone())); + }).cloned()); push(P(ast::Item { attrs: attrs, ..(*newitem).clone() @@ -410,7 +410,7 @@ impl<'a> TraitDef<'a> { let mut ty_params = ty_params.into_vec(); // Copy the lifetimes - lifetimes.extend(generics.lifetimes.iter().map(|l| (*l).clone())); + lifetimes.extend(generics.lifetimes.iter().cloned()); // Create the type parameters. ty_params.extend(generics.ty_params.iter().map(|ty_param| { @@ -445,14 +445,14 @@ impl<'a> TraitDef<'a> { span: self.span, bound_lifetimes: wb.bound_lifetimes.clone(), bounded_ty: wb.bounded_ty.clone(), - bounds: OwnedSlice::from_vec(wb.bounds.iter().map(|b| b.clone()).collect()) + bounds: OwnedSlice::from_vec(wb.bounds.iter().cloned().collect()) }) } ast::WherePredicate::RegionPredicate(ref rb) => { ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate { span: self.span, lifetime: rb.lifetime, - bounds: rb.bounds.iter().map(|b| b.clone()).collect() + bounds: rb.bounds.iter().cloned().collect() }) } ast::WherePredicate::EqPredicate(ref we) => { @@ -500,7 +500,7 @@ impl<'a> TraitDef<'a> { let opt_trait_ref = Some(trait_ref); let ident = ast_util::impl_pretty_name(&opt_trait_ref, &*self_type); let mut a = vec![attr]; - a.extend(self.attributes.iter().map(|a| a.clone())); + a.extend(self.attributes.iter().cloned()); cx.item( self.span, ident, diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 7a3a3562bdfdc..d1dee115b6bcd 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -179,7 +179,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) return DummyResult::expr(sp); } Ok(bytes) => { - let bytes = bytes.iter().map(|x| *x).collect(); + let bytes = bytes.iter().cloned().collect(); base::MacExpr::new(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes)))) } } diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index d752e34c11253..a3224c25d0957 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -283,7 +283,7 @@ pub fn parse(sess: &ParseSess, -> ParseResult { let mut cur_eis = Vec::new(); cur_eis.push(initial_matcher_pos(Rc::new(ms.iter() - .map(|x| (*x).clone()) + .cloned() .collect()), None, rdr.peek().sp.lo)); diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index f322cf8bad09c..1a6cf7d07f19d 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -159,7 +159,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, None, None, arg.iter() - .map(|x| (*x).clone()) + .cloned() .collect(), true); match parse(cx.parse_sess(), cx.cfg(), arg_rdr, lhs_tt) { diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index b17fc7fe82e6c..c0823e04288e3 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -61,7 +61,7 @@ pub fn doc_comment_style(comment: &str) -> ast::AttrStyle { pub fn strip_doc_comment_decoration(comment: &str) -> String { /// remove whitespace-only lines from the start/end of lines - fn vertical_trim(lines: Vec ) -> Vec { + fn vertical_trim(lines: Vec) -> Vec { let mut i = 0; let mut j = lines.len(); // first line of all-stars should be omitted @@ -82,7 +82,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> String { while j > i && lines[j - 1].trim().is_empty() { j -= 1; } - return lines[i..j].iter().map(|x| (*x).clone()).collect(); + lines[i..j].iter().cloned().collect() } /// remove a "[ \t]*\*" block from each line, if possible diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 407740e580d2e..f14cd5247769d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -240,9 +240,8 @@ macro_rules! maybe_whole { fn maybe_append(mut lhs: Vec, rhs: Option>) -> Vec { - match rhs { - Some(ref attrs) => lhs.extend(attrs.iter().map(|a| a.clone())), - None => {} + if let Some(ref attrs) = rhs { + lhs.extend(attrs.iter().cloned()) } lhs } @@ -467,7 +466,7 @@ impl<'a> Parser<'a> { debug!("commit_expr {:?}", e); if let ExprPath(..) = e.node { // might be unit-struct construction; check for recoverableinput error. - let mut expected = edible.iter().map(|x| x.clone()).collect::>(); + let mut expected = edible.iter().cloned().collect::>(); expected.push_all(inedible); self.check_for_erroneous_unit_struct_expecting(&expected[]); } @@ -485,7 +484,7 @@ impl<'a> Parser<'a> { if self.last_token .as_ref() .map_or(false, |t| t.is_ident() || t.is_path()) { - let mut expected = edible.iter().map(|x| x.clone()).collect::>(); + let mut expected = edible.iter().cloned().collect::>(); expected.push_all(&inedible[]); self.check_for_erroneous_unit_struct_expecting( &expected[]); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 583095e157427..8f1acde15460c 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -983,15 +983,14 @@ impl<'a> State<'a> { try!(self.word_nbsp("trait")); try!(self.print_ident(item.ident)); try!(self.print_generics(generics)); - let bounds: Vec<_> = bounds.iter().map(|b| b.clone()).collect(); let mut real_bounds = Vec::with_capacity(bounds.len()); - for b in bounds { - if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = b { + for b in bounds.iter() { + if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = *b { try!(space(&mut self.s)); try!(self.word_space("for ?")); try!(self.print_trait_ref(&ptr.trait_ref)); } else { - real_bounds.push(b); + real_bounds.push(b.clone()); } } try!(self.print_bounds(":", &real_bounds[])); diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index 5bf0862e0a1d6..273b014011f05 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -134,7 +134,7 @@ fn run(writer: &mut W) -> std::old_io::IoResult<()> { ('t', 0.3015094502008)]; try!(make_fasta(writer, ">ONE Homo sapiens alu\n", - alu.as_bytes().iter().cycle().map(|c| *c), n * 2)); + alu.as_bytes().iter().cycle().cloned(), n * 2)); try!(make_fasta(writer, ">TWO IUB ambiguity codes\n", AAGen::new(rng, iub), n * 3)); try!(make_fasta(writer, ">THREE Homo sapiens frequency\n", diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs index d061403d5901d..59abd63e12d59 100644 --- a/src/test/bench/shootout-meteor.rs +++ b/src/test/bench/shootout-meteor.rs @@ -270,7 +270,7 @@ fn handle_sol(raw_sol: &List, data: &mut Data) { // reverse order, i.e. the board rotated by half a turn. data.nb += 2; let sol1 = to_vec(raw_sol); - let sol2: Vec = sol1.iter().rev().map(|x| *x).collect(); + let sol2: Vec = sol1.iter().rev().cloned().collect(); if data.nb == 2 { data.min = sol1.clone(); From 061206b9c75cf89b94dac1a2f358a0c649d796ae Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Sun, 15 Feb 2015 05:19:50 +0000 Subject: [PATCH 09/76] Remove usage of .map(|&foo| foo) --- src/libcore/iter.rs | 8 ++-- src/libcoretest/iter.rs | 42 ++++++++++----------- src/librand/isaac.rs | 4 +- src/librustc/middle/dataflow.rs | 4 +- src/librustc/middle/subst.rs | 2 +- src/librustc/middle/traits/object_safety.rs | 2 +- src/librustc/middle/traits/select.rs | 2 +- src/librustc/middle/ty.rs | 2 +- src/librustc_trans/trans/closure.rs | 2 +- src/librustc_typeck/check/mod.rs | 2 +- src/libstd/old_path/posix.rs | 4 +- src/libstd/old_path/windows.rs | 4 +- src/libstd/rand/mod.rs | 2 +- src/libsyntax/diagnostics/registry.rs | 2 +- src/libsyntax/parse/parser.rs | 2 +- src/libterm/terminfo/parm.rs | 2 +- src/test/bench/shootout-meteor.rs | 2 +- 17 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index c5e0966720fd2..d9ee34731ceb6 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -540,7 +540,7 @@ pub trait IteratorExt: Iterator + Sized { /// /// let a = [1, 4, 2, 3, 8, 9, 6]; /// let sum = a.iter() - /// .map(|&x| x) + /// .cloned() /// .inspect(|&x| println!("filtering {}", x)) /// .filter(|&x| x % 2 == 0) /// .inspect(|&x| println!("{} made it through", x)) @@ -579,7 +579,7 @@ pub trait IteratorExt: Iterator + Sized { /// /// ``` /// let a = [1, 2, 3, 4, 5]; - /// let b: Vec<_> = a.iter().map(|&x| x).collect(); + /// let b: Vec<_> = a.iter().cloned().collect(); /// assert_eq!(a, b); /// ``` #[inline] @@ -955,7 +955,7 @@ pub trait IteratorExt: Iterator + Sized { /// /// ``` /// let a = [(1, 2), (3, 4)]; - /// let (left, right): (Vec<_>, Vec<_>) = a.iter().map(|&x| x).unzip(); + /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip(); /// assert_eq!([1, 3], left); /// assert_eq!([2, 4], right); /// ``` @@ -1160,7 +1160,7 @@ pub trait AdditiveIterator { /// use std::iter::AdditiveIterator; /// /// let a = [1i32, 2, 3, 4, 5]; - /// let mut it = a.iter().map(|&x| x); + /// let mut it = a.iter().cloned(); /// assert!(it.sum() == 15); /// ``` fn sum(self) -> A; diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 88777da0bcd35..4eee0454f5d25 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -91,7 +91,7 @@ fn test_iterator_chain() { assert_eq!(i, expected.len()); let ys = count(30, 10).take(4); - let mut it = xs.iter().map(|&x| x).chain(ys); + let mut it = xs.iter().cloned().chain(ys); let mut i = 0; for x in it { assert_eq!(x, expected[i]); @@ -119,7 +119,7 @@ fn test_iterator_enumerate() { #[test] fn test_iterator_peekable() { let xs = vec![0, 1, 2, 3, 4, 5]; - let mut it = xs.iter().map(|&x|x).peekable(); + let mut it = xs.iter().cloned().peekable(); assert_eq!(it.len(), 6); assert_eq!(it.peek().unwrap(), &0); @@ -259,7 +259,7 @@ fn test_inspect() { let mut n = 0; let ys = xs.iter() - .map(|&x| x) + .cloned() .inspect(|_| n += 1) .collect::>(); @@ -329,33 +329,33 @@ fn test_iterator_len() { #[test] fn test_iterator_sum() { let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - assert_eq!(v[..4].iter().map(|&x| x).sum(), 6); - assert_eq!(v.iter().map(|&x| x).sum(), 55); - assert_eq!(v[..0].iter().map(|&x| x).sum(), 0); + assert_eq!(v[..4].iter().cloned().sum(), 6); + assert_eq!(v.iter().cloned().sum(), 55); + assert_eq!(v[..0].iter().cloned().sum(), 0); } #[test] fn test_iterator_product() { let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - assert_eq!(v[..4].iter().map(|&x| x).product(), 0); - assert_eq!(v[1..5].iter().map(|&x| x).product(), 24); - assert_eq!(v[..0].iter().map(|&x| x).product(), 1); + assert_eq!(v[..4].iter().cloned().product(), 0); + assert_eq!(v[1..5].iter().cloned().product(), 24); + assert_eq!(v[..0].iter().cloned().product(), 1); } #[test] fn test_iterator_max() { let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - assert_eq!(v[..4].iter().map(|&x| x).max(), Some(3)); - assert_eq!(v.iter().map(|&x| x).max(), Some(10)); - assert_eq!(v[..0].iter().map(|&x| x).max(), None); + assert_eq!(v[..4].iter().cloned().max(), Some(3)); + assert_eq!(v.iter().cloned().max(), Some(10)); + assert_eq!(v[..0].iter().cloned().max(), None); } #[test] fn test_iterator_min() { let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - assert_eq!(v[..4].iter().map(|&x| x).min(), Some(0)); - assert_eq!(v.iter().map(|&x| x).min(), Some(0)); - assert_eq!(v[..0].iter().map(|&x| x).min(), None); + assert_eq!(v[..4].iter().cloned().min(), Some(0)); + assert_eq!(v.iter().cloned().min(), Some(0)); + assert_eq!(v[..0].iter().cloned().min(), None); } #[test] @@ -373,7 +373,7 @@ fn test_iterator_size_hint() { assert_eq!(c.clone().take_while(|_| false).size_hint(), (0, None)); assert_eq!(c.clone().skip_while(|_| false).size_hint(), (0, None)); assert_eq!(c.clone().enumerate().size_hint(), (uint::MAX, None)); - assert_eq!(c.clone().chain(vi.clone().map(|&i| i)).size_hint(), (uint::MAX, None)); + assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (uint::MAX, None)); assert_eq!(c.clone().zip(vi.clone()).size_hint(), (10, Some(10))); assert_eq!(c.clone().scan(0, |_,_| Some(0)).size_hint(), (0, None)); assert_eq!(c.clone().filter(|_| false).size_hint(), (0, None)); @@ -398,7 +398,7 @@ fn test_iterator_size_hint() { #[test] fn test_collect() { let a = vec![1, 2, 3, 4, 5]; - let b: Vec = a.iter().map(|&x| x).collect(); + let b: Vec = a.iter().cloned().collect(); assert!(a == b); } @@ -471,7 +471,7 @@ fn test_rev() { let mut it = xs.iter(); it.next(); it.next(); - assert!(it.rev().map(|&x| x).collect::>() == + assert!(it.rev().cloned().collect::>() == vec![16, 14, 12, 10, 8, 6]); } @@ -508,7 +508,7 @@ fn test_double_ended_map() { #[test] fn test_double_ended_enumerate() { let xs = [1, 2, 3, 4, 5, 6]; - let mut it = xs.iter().map(|&x| x).enumerate(); + let mut it = xs.iter().cloned().enumerate(); assert_eq!(it.next(), Some((0, 1))); assert_eq!(it.next(), Some((1, 2))); assert_eq!(it.next_back(), Some((5, 6))); @@ -522,8 +522,8 @@ fn test_double_ended_enumerate() { fn test_double_ended_zip() { let xs = [1, 2, 3, 4, 5, 6]; let ys = [1, 2, 3, 7]; - let a = xs.iter().map(|&x| x); - let b = ys.iter().map(|&x| x); + let a = xs.iter().cloned(); + let b = ys.iter().cloned(); let mut it = a.zip(b); assert_eq!(it.next(), Some((1, 1))); assert_eq!(it.next(), Some((2, 2))); diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs index f15523fc010b6..701749ff3443f 100644 --- a/src/librand/isaac.rs +++ b/src/librand/isaac.rs @@ -215,7 +215,7 @@ impl<'a> SeedableRng<&'a [u32]> for IsaacRng { fn reseed(&mut self, seed: &'a [u32]) { // make the seed into [seed[0], seed[1], ..., seed[seed.len() // - 1], 0, 0, ...], to fill rng.rsl. - let seed_iter = seed.iter().map(|&x| x).chain(repeat(0u32)); + let seed_iter = seed.iter().cloned().chain(repeat(0u32)); for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) { *rsl_elem = seed_elem; @@ -458,7 +458,7 @@ impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng { fn reseed(&mut self, seed: &'a [u64]) { // make the seed into [seed[0], seed[1], ..., seed[seed.len() // - 1], 0, 0, ...], to fill rng.rsl. - let seed_iter = seed.iter().map(|&x| x).chain(repeat(0u64)); + let seed_iter = seed.iter().cloned().chain(repeat(0u64)); for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) { *rsl_elem = seed_elem; diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index b792a44d4d89a..307423734b3bf 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -89,7 +89,7 @@ struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O: 'a> { } fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap) -> CFGIndex { - let opt_cfgindex = index.get(&id).map(|&i|i); + let opt_cfgindex = index.get(&id).cloned(); opt_cfgindex.unwrap_or_else(|| { panic!("nodeid_to_index does not have entry for NodeId {}", id); }) @@ -400,7 +400,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { let mut changed = false; for &node_id in &edge.data.exiting_scopes { - let opt_cfg_idx = self.nodeid_to_index.get(&node_id).map(|&i|i); + let opt_cfg_idx = self.nodeid_to_index.get(&node_id).cloned(); match opt_cfg_idx { Some(cfg_idx) => { let (start, end) = self.compute_id_range(cfg_idx); diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index e27e7a8024685..dc4d0623e9ee9 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -113,7 +113,7 @@ impl<'tcx> Substs<'tcx> { } pub fn self_ty(&self) -> Option> { - self.types.get_self().map(|&t| t) + self.types.get_self().cloned() } pub fn with_self_ty(&self, self_ty: Ty<'tcx>) -> Substs<'tcx> { diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs index b2701ae875c0c..7442dd47f7bb7 100644 --- a/src/librustc/middle/traits/object_safety.rs +++ b/src/librustc/middle/traits/object_safety.rs @@ -57,7 +57,7 @@ pub fn is_object_safe<'tcx>(tcx: &ty::ctxt<'tcx>, { // Because we query yes/no results frequently, we keep a cache: let cached_result = - tcx.object_safety_cache.borrow().get(&trait_ref.def_id()).map(|&r| r); + tcx.object_safety_cache.borrow().get(&trait_ref.def_id()).cloned(); let result = cached_result.unwrap_or_else(|| { diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index b21b42fdbfcce..a488627c7f362 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -1581,7 +1581,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::substd_enum_variants(self.tcx(), def_id, substs) .iter() .flat_map(|variant| variant.args.iter()) - .map(|&ty| ty) + .cloned() .collect(); nominal(self, bound, def_id, types) } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8ca54cce8e363..ce5f9e213f741 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4144,7 +4144,7 @@ pub fn positional_element_ty<'tcx>(cx: &ctxt<'tcx>, variant: Option) -> Option> { match (&ty.sty, variant) { - (&ty_tup(ref v), None) => v.get(i).map(|&t| t), + (&ty_tup(ref v), None) => v.get(i).cloned(), (&ty_struct(def_id, substs), None) => lookup_struct_fields(cx, def_id) diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index f92df999e6049..ed75330ffcc70 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -208,7 +208,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, let function_type = typer.closure_type(closure_id, param_substs); let freevars: Vec = - ty::with_freevars(tcx, id, |fv| fv.iter().map(|&fv| fv).collect()); + ty::with_freevars(tcx, id, |fv| fv.iter().cloned().collect()); let sig = ty::erase_late_bound_regions(tcx, &function_type.sig); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1ba2e38201c63..f6764de97b78e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -640,7 +640,7 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, // Remember return type so that regionck can access it later. let mut fn_sig_tys: Vec = arg_tys.iter() - .map(|&ty| ty) + .cloned() .collect(); if let ty::FnConverging(ret_ty) = ret_ty { diff --git a/src/libstd/old_path/posix.rs b/src/libstd/old_path/posix.rs index 6bf2a30b7b184..d5125f03a7169 100644 --- a/src/libstd/old_path/posix.rs +++ b/src/libstd/old_path/posix.rs @@ -1172,7 +1172,7 @@ mod tests { let exp: &[&[u8]] = &[$($exp),*]; assert_eq!(comps, exp); let comps = path.components().rev().collect::>(); - let exp = exp.iter().rev().map(|&x|x).collect::>(); + let exp = exp.iter().rev().cloned().collect::>(); assert_eq!(comps, exp) } ) @@ -1204,7 +1204,7 @@ mod tests { let exp: &[Option<&str>] = &$exp; assert_eq!(comps, exp); let comps = path.str_components().rev().collect::>>(); - let exp = exp.iter().rev().map(|&x|x).collect::>>(); + let exp = exp.iter().rev().cloned().collect::>>(); assert_eq!(comps, exp); } ) diff --git a/src/libstd/old_path/windows.rs b/src/libstd/old_path/windows.rs index 54c070e1b7db8..e485dae3503c8 100644 --- a/src/libstd/old_path/windows.rs +++ b/src/libstd/old_path/windows.rs @@ -2226,7 +2226,7 @@ mod tests { assert_eq!(comps, exp); let comps = path.str_components().rev().map(|x|x.unwrap()) .collect::>(); - let exp = exp.iter().rev().map(|&x|x).collect::>(); + let exp = exp.iter().rev().cloned().collect::>(); assert_eq!(comps, exp); } ); @@ -2282,7 +2282,7 @@ mod tests { let exp: &[&[u8]] = &$exp; assert_eq!(comps, exp); let comps = path.components().rev().collect::>(); - let exp = exp.iter().rev().map(|&x|x).collect::>(); + let exp = exp.iter().rev().cloned().collect::>(); assert_eq!(comps, exp); } ) diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs index 8f9e966cbb2b7..5b888c7612d19 100644 --- a/src/libstd/rand/mod.rs +++ b/src/libstd/rand/mod.rs @@ -547,7 +547,7 @@ mod test { #[test] fn test_choose() { let mut r = thread_rng(); - assert_eq!(r.choose(&[1, 1, 1]).map(|&x|x), Some(1)); + assert_eq!(r.choose(&[1, 1, 1]).cloned(), Some(1)); let v: &[int] = &[]; assert_eq!(r.choose(v), None); diff --git a/src/libsyntax/diagnostics/registry.rs b/src/libsyntax/diagnostics/registry.rs index 968fceb6f6fd0..a6cfd1a5a9ac3 100644 --- a/src/libsyntax/diagnostics/registry.rs +++ b/src/libsyntax/diagnostics/registry.rs @@ -17,7 +17,7 @@ pub struct Registry { impl Registry { pub fn new(descriptions: &[(&'static str, &'static str)]) -> Registry { - Registry { descriptions: descriptions.iter().map(|&tuple| tuple).collect() } + Registry { descriptions: descriptions.iter().cloned().collect() } } pub fn find_description(&self, code: &str) -> Option<&'static str> { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f14cd5247769d..f6ec4816b63fc 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1705,7 +1705,7 @@ impl<'a> Parser<'a> { (true, LitBinary(parse::binary_lit(i.as_str()))), token::BinaryRaw(i, _) => (true, - LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect()))), + LitBinary(Rc::new(i.as_str().as_bytes().iter().cloned().collect()))), }; if suffix_illegal { diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs index 82b5ec11d95d1..0b577f8de74c2 100644 --- a/src/libterm/terminfo/parm.rs +++ b/src/libterm/terminfo/parm.rs @@ -608,7 +608,7 @@ mod test { Result, String> { let mut u8v: Vec<_> = fmt.bytes().collect(); - u8v.extend(cap.as_bytes().iter().map(|&b| b)); + u8v.extend(cap.bytes()); expand(&u8v, params, vars) } diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs index 59abd63e12d59..4f69600be6c00 100644 --- a/src/test/bench/shootout-meteor.rs +++ b/src/test/bench/shootout-meteor.rs @@ -202,7 +202,7 @@ fn filter_masks(masks: &mut Vec>>) { for i in 0..masks.len() { for j in 0..(*masks)[i].len() { masks[i][j] = - (*masks)[i][j].iter().map(|&m| m) + (*masks)[i][j].iter().cloned() .filter(|&m| !is_board_unfeasible(m, masks)) .collect(); } From d2f54e663400b98c368710669ad9a966fa950803 Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Sun, 15 Feb 2015 06:45:23 +0000 Subject: [PATCH 10/76] librustc: implement Clone for middle::ty::FreeVar --- src/librustc/middle/ty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index ce5f9e213f741..0ed74fc91d4d4 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -6636,7 +6636,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec, } /// A free variable referred to in a function. -#[derive(Copy, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable)] pub struct Freevar { /// The variable being accessed free. pub def: def::Def, From b8527c07dc401a39a051da2ca886b24d8be7e589 Mon Sep 17 00:00:00 2001 From: Ryan Riginding Date: Wed, 18 Feb 2015 09:16:22 +0100 Subject: [PATCH 11/76] Fixed link in ffi documentation --- src/doc/trpl/ffi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/ffi.md b/src/doc/trpl/ffi.md index f2b95f19edce2..d1b32ba161dbe 100644 --- a/src/doc/trpl/ffi.md +++ b/src/doc/trpl/ffi.md @@ -541,6 +541,6 @@ pub extern fn hello_rust() -> *const u8 { The `extern` makes this function adhere to the C calling convention, as discussed above in "[Foreign Calling -Conventions](guide-ffi.html#foreign-calling-conventions)". The `no_mangle` +Conventions](ffi.html#foreign-calling-conventions)". The `no_mangle` attribute turns off Rust's name mangling, so that it is easier to link to. From 52b5150cfd3dfcdf518675e9073f03e061a63a53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Mon, 2 Feb 2015 21:45:49 +0100 Subject: [PATCH 12/76] Avoid ptrtoint when checking if a pointer is null Casting the pointer to an integer requires a ptrtoint, while casting 0 to a pointer is directly folded to a `null` value. --- src/libcore/ptr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 072c60c7036cf..2779e67c74300 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -303,7 +303,7 @@ impl PtrExt for *const T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn is_null(self) -> bool { self as usize == 0 } + fn is_null(self) -> bool { self == 0 as *const T } #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -330,7 +330,7 @@ impl PtrExt for *mut T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn is_null(self) -> bool { self as usize == 0 } + fn is_null(self) -> bool { self == 0 as *mut T } #[inline] #[stable(feature = "rust1", since = "1.0.0")] From 7412d1b2eff1c77241c54fa39508e7049d71ec7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Mon, 2 Feb 2015 19:25:44 +0100 Subject: [PATCH 13/76] Eliminate excessive null-checks from slice iterators The data pointer used in the slice is never null, using assume() to tell LLVM about it gets rid of various unneeded null checks when iterating over the slice. Since the snapshot compiler is still using an older LLVM version, omit the call in stage0, because compile times explode otherwise. Benchmarks from #18193 ```` running 5 tests test _range ... bench: 33329 ns/iter (+/- 417) test assembly ... bench: 33299 ns/iter (+/- 58) test enumerate ... bench: 33318 ns/iter (+/- 83) test iter ... bench: 33311 ns/iter (+/- 130) test position ... bench: 33300 ns/iter (+/- 47) test result: ok. 0 passed; 0 failed; 0 ignored; 5 measured ```` Fixes #18193 --- src/libcollections/vec.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index bde733644b5b5..25226afd8c9b7 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -56,6 +56,7 @@ use core::cmp::{Ordering}; use core::default::Default; use core::fmt; use core::hash::{self, Hash}; +use core::intrinsics::assume; use core::iter::{repeat, FromIterator, IntoIterator}; use core::marker::{self, ContravariantLifetime, InvariantType}; use core::mem; @@ -1587,8 +1588,12 @@ impl AsSlice for Vec { #[stable(feature = "rust1", since = "1.0.0")] fn as_slice(&self) -> &[T] { unsafe { + let p = *self.ptr; + if cfg!(not(stage0)) { // NOTE remove cfg after next snapshot + assume(p != 0 as *mut T); + } mem::transmute(RawSlice { - data: *self.ptr, + data: p, len: self.len }) } From f82e2310b3b35bc1d137712576d2d16b82e03fcb Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 18 Feb 2015 14:37:05 +0100 Subject: [PATCH 14/76] Audit `core::borrow` for use of `int/uint`: use `i32` in doc example. --- src/libcore/borrow.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 035443e9c3f35..3131952d94dbb 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -124,7 +124,7 @@ impl ToOwned for T where T: Clone { /// ```rust /// use std::borrow::Cow; /// -/// fn abs_all(input: &mut Cow, [int]>) { +/// fn abs_all(input: &mut Cow, [i32]>) { /// for i in 0..input.len() { /// let v = input[i]; /// if v < 0 { From 343909bca1a3903bc6df51007723601ac5a103c0 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 18 Feb 2015 14:39:06 +0100 Subject: [PATCH 15/76] Audit `core::cmp` for `int/uint`. * cast 3-valued `core::cmp::Ordering` to `i32`, not `int`. * use `isize`/`usize` in the impl macros. --- src/libcore/cmp.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 19ec245300d02..b37bad5f7546c 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -215,7 +215,7 @@ impl Ord for Ordering { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn cmp(&self, other: &Ordering) -> Ordering { - (*self as int).cmp(&(*other as int)) + (*self as i32).cmp(&(*other as i32)) } } @@ -224,7 +224,7 @@ impl PartialOrd for Ordering { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn partial_cmp(&self, other: &Ordering) -> Option { - (*self as int).partial_cmp(&(*other as int)) + (*self as i32).partial_cmp(&(*other as i32)) } } @@ -482,7 +482,7 @@ mod impls { } partial_eq_impl! { - bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 + bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } macro_rules! eq_impl { @@ -492,7 +492,7 @@ mod impls { )*) } - eq_impl! { () bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 } + eq_impl! { () bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 } macro_rules! partial_ord_impl { ($($t:ty)*) => ($( @@ -535,7 +535,7 @@ mod impls { } } - partial_ord_impl! { char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 } + partial_ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } macro_rules! ord_impl { ($($t:ty)*) => ($( @@ -565,7 +565,7 @@ mod impls { } } - ord_impl! { char uint u8 u16 u32 u64 int i8 i16 i32 i64 } + ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 } // & pointers From e240cb919b58975a0b647a613841da8819b672cf Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 18 Feb 2015 14:41:13 +0100 Subject: [PATCH 16/76] Audit `core::default` for `int`/`uint` usage. * Use `i32` (`u32`) in doc examples, not `int` (`u32`). * Switch impl macros to use `isize`/`usize` rather than `int`/`uint`. --- src/libcore/default.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libcore/default.rs b/src/libcore/default.rs index d79b613f58949..7f46d9cbe5021 100644 --- a/src/libcore/default.rs +++ b/src/libcore/default.rs @@ -16,7 +16,7 @@ //! //! ``` //! struct SomeOptions { -//! foo: int, +//! foo: i32, //! bar: f32, //! } //! ``` @@ -28,7 +28,7 @@ //! //! #[derive(Default)] //! struct SomeOptions { -//! foo: int, +//! foo: i32, //! bar: f32, //! } //! @@ -56,7 +56,7 @@ //! //! #[derive(Default)] //! struct SomeOptions { -//! foo: int, +//! foo: i32, //! bar: f32, //! baz: Kind, //! } @@ -73,7 +73,7 @@ //! # use std::default::Default; //! # #[derive(Default)] //! # struct SomeOptions { -//! # foo: int, +//! # foo: i32, //! # bar: f32, //! # } //! fn main() { @@ -93,7 +93,7 @@ /// ``` /// #[derive(Default)] /// struct SomeOptions { -/// foo: int, +/// foo: i32, /// bar: f32, /// } /// ``` @@ -113,7 +113,7 @@ pub trait Default { /// /// let i: i8 = Default::default(); /// let (x, y): (Option, f64) = Default::default(); - /// let (a, b, (c, d)): (int, uint, (bool, bool)) = Default::default(); + /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default(); /// ``` /// /// Making your own: @@ -150,13 +150,13 @@ default_impl! { (), () } default_impl! { bool, false } default_impl! { char, '\x00' } -default_impl! { uint, 0 } +default_impl! { usize, 0 } default_impl! { u8, 0 } default_impl! { u16, 0 } default_impl! { u32, 0 } default_impl! { u64, 0 } -default_impl! { int, 0 } +default_impl! { isize, 0 } default_impl! { i8, 0 } default_impl! { i16, 0 } default_impl! { i32, 0 } From fc0f6e86b6aead84fa0692340a30cce6d3622365 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 18 Feb 2015 14:43:43 +0100 Subject: [PATCH 17/76] Audit `core::intrinsics` for `int`/`uint`: `size_of`/`align_of` use `usize`. Likewise, `fn offset` takes an `isize`. --- src/libcore/intrinsics.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 050c144b74299..b2ee95963878e 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -50,10 +50,10 @@ pub type GlueFn = extern "Rust" fn(*const i8); #[derive(Copy)] pub struct TyDesc { // sizeof(T) - pub size: uint, + pub size: usize, // alignof(T) - pub align: uint, + pub align: usize, // Called when a value of type `T` is no longer needed pub drop_glue: GlueFn, @@ -186,15 +186,15 @@ extern "rust-intrinsic" { /// would *exactly* overwrite a value. When laid out in vectors /// and structures there may be additional padding between /// elements. - pub fn size_of() -> uint; + pub fn size_of() -> usize; /// Move a value to an uninitialized memory location. /// /// Drop glue is not run on the destination. pub fn move_val_init(dst: &mut T, src: T); - pub fn min_align_of() -> uint; - pub fn pref_align_of() -> uint; + pub fn min_align_of() -> usize; + pub fn pref_align_of() -> usize; /// Get a static pointer to a type descriptor. pub fn get_tydesc() -> *const TyDesc; @@ -253,7 +253,7 @@ extern "rust-intrinsic" { /// /// This is implemented as an intrinsic to avoid converting to and from an /// integer, since the conversion would throw away aliasing information. - pub fn offset(dst: *const T, offset: int) -> *const T; + pub fn offset(dst: *const T, offset: isize) -> *const T; /// Copies `count * size_of` bytes from `src` to `dst`. The source /// and destination may *not* overlap. @@ -294,7 +294,7 @@ extern "rust-intrinsic" { /// } /// ``` #[unstable(feature = "core")] - pub fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint); + pub fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: usize); /// Copies `count * size_of` bytes from `src` to `dst`. The source /// and destination may overlap. @@ -324,13 +324,13 @@ extern "rust-intrinsic" { /// ``` /// #[unstable(feature = "core")] - pub fn copy_memory(dst: *mut T, src: *const T, count: uint); + pub fn copy_memory(dst: *mut T, src: *const T, count: usize); /// Invokes memset on the specified pointer, setting `count * size_of::()` /// bytes of memory starting at `dst` to `c`. #[unstable(feature = "core", reason = "uncertain about naming and semantics")] - pub fn set_memory(dst: *mut T, val: u8, count: uint); + pub fn set_memory(dst: *mut T, val: u8, count: usize); /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with /// a size of `count` * `size_of::()` and an alignment of @@ -338,19 +338,19 @@ extern "rust-intrinsic" { /// /// The volatile parameter parameter is set to `true`, so it will not be optimized out. pub fn volatile_copy_nonoverlapping_memory(dst: *mut T, src: *const T, - count: uint); + count: usize); /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with /// a size of `count` * `size_of::()` and an alignment of /// `min_align_of::()` /// /// The volatile parameter parameter is set to `true`, so it will not be optimized out. - pub fn volatile_copy_memory(dst: *mut T, src: *const T, count: uint); + pub fn volatile_copy_memory(dst: *mut T, src: *const T, count: usize); /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a /// size of `count` * `size_of::()` and an alignment of /// `min_align_of::()`. /// /// The volatile parameter parameter is set to `true`, so it will not be optimized out. - pub fn volatile_set_memory(dst: *mut T, val: u8, count: uint); + pub fn volatile_set_memory(dst: *mut T, val: u8, count: usize); /// Perform a volatile load from the `src` pointer. pub fn volatile_load(src: *const T) -> T; From 2594d56e32bd5a86befbb9e072b272251bbdfc9f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 05:16:02 -0500 Subject: [PATCH 18/76] Introduce the new phantomdata/phantomfn markers and integrate them into variance inference; fix various bugs in variance inference so that it considers the correct set of constraints; modify infer to consider the results of variance inference for type arguments. --- src/libcore/fmt/mod.rs | 7 +- src/libcore/marker.rs | 295 ++++---------- src/librustc/middle/infer/bivariate.rs | 128 ++++++ src/librustc/middle/infer/combine.rs | 146 +++---- src/librustc/middle/infer/equate.rs | 27 +- src/librustc/middle/infer/glb.rs | 47 ++- src/librustc/middle/infer/lub.rs | 47 ++- src/librustc/middle/infer/mod.rs | 1 + src/librustc/middle/infer/sub.rs | 49 ++- src/librustc/middle/infer/type_variable.rs | 5 +- src/librustc/middle/lang_items.rs | 9 +- src/librustc/middle/traits/select.rs | 12 +- .../constrained_type_params.rs | 61 +++ src/librustc_typeck/variance.rs | 384 ++++++++++++------ .../variance-contravariant-arg-object.rs | 31 ++ .../variance-contravariant-arg-trait-match.rs | 31 ++ ...variance-contravariant-self-trait-match.rs | 31 ++ .../variance-covariant-arg-object.rs | 31 ++ .../variance-covariant-arg-trait-match.rs | 31 ++ .../variance-covariant-self-trait-match.rs | 31 ++ .../variance-invariant-arg-object.rs | 31 ++ .../variance-invariant-arg-trait-match.rs | 31 ++ .../variance-invariant-self-trait-match.rs | 31 ++ .../variance-regions-unused-direct.rs | 25 ++ .../variance-regions-unused-indirect.rs | 21 + .../compile-fail/variance-trait-bounds.rs | 64 +++ .../compile-fail/variance-types-bounds.rs | 74 ++++ src/test/compile-fail/variance-types.rs | 51 +++ .../variance-unused-region-param.rs | 17 + .../variance-unused-type-param.rs | 36 ++ .../variance-use-contravariant-struct-1.rs | 24 ++ .../variance-use-contravariant-struct-2.rs | 26 ++ .../variance-use-covariant-struct-1.rs | 23 ++ .../variance-use-covariant-struct-2.rs | 25 ++ .../variance-use-invariant-struct-1.rs | 31 ++ ...ariance-intersection-of-ref-and-opt-ref.rs | 34 ++ src/test/run-pass/variance-trait-matching.rs | 49 +++ src/test/run-pass/variance-vec-covariant.rs | 28 ++ 38 files changed, 1522 insertions(+), 503 deletions(-) create mode 100644 src/librustc/middle/infer/bivariate.rs create mode 100644 src/librustc_typeck/constrained_type_params.rs create mode 100644 src/test/compile-fail/variance-contravariant-arg-object.rs create mode 100644 src/test/compile-fail/variance-contravariant-arg-trait-match.rs create mode 100644 src/test/compile-fail/variance-contravariant-self-trait-match.rs create mode 100644 src/test/compile-fail/variance-covariant-arg-object.rs create mode 100644 src/test/compile-fail/variance-covariant-arg-trait-match.rs create mode 100644 src/test/compile-fail/variance-covariant-self-trait-match.rs create mode 100644 src/test/compile-fail/variance-invariant-arg-object.rs create mode 100644 src/test/compile-fail/variance-invariant-arg-trait-match.rs create mode 100644 src/test/compile-fail/variance-invariant-self-trait-match.rs create mode 100644 src/test/compile-fail/variance-regions-unused-direct.rs create mode 100644 src/test/compile-fail/variance-regions-unused-indirect.rs create mode 100644 src/test/compile-fail/variance-trait-bounds.rs create mode 100644 src/test/compile-fail/variance-types-bounds.rs create mode 100644 src/test/compile-fail/variance-types.rs create mode 100644 src/test/compile-fail/variance-unused-region-param.rs create mode 100644 src/test/compile-fail/variance-unused-type-param.rs create mode 100644 src/test/compile-fail/variance-use-contravariant-struct-1.rs create mode 100644 src/test/compile-fail/variance-use-contravariant-struct-2.rs create mode 100644 src/test/compile-fail/variance-use-covariant-struct-1.rs create mode 100644 src/test/compile-fail/variance-use-covariant-struct-2.rs create mode 100644 src/test/compile-fail/variance-use-invariant-struct-1.rs create mode 100644 src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs create mode 100644 src/test/run-pass/variance-trait-matching.rs create mode 100644 src/test/run-pass/variance-vec-covariant.rs diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 67c8c9fec09ab..a2c1bbc03317e 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -16,7 +16,7 @@ use any; use cell::{Cell, RefCell, Ref, RefMut, BorrowState}; use char::CharExt; use iter::{Iterator, IteratorExt}; -use marker::{Copy, Sized}; +use marker::{Copy, PhantomData, Sized}; use mem; use option::Option; use option::Option::{Some, None}; @@ -914,6 +914,11 @@ impl Debug for () { f.pad("()") } } +impl Debug for PhantomData { + fn fmt(&self, f: &mut Formatter) -> Result { + f.pad("PhantomData") + } +} #[stable(feature = "rust1", since = "1.0.0")] impl Debug for Cell { diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 56e1c5dedc1ce..5c7ec423e7c9a 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -26,6 +26,10 @@ #![stable(feature = "rust1", since = "1.0.0")] use clone::Clone; +use cmp; +use option::Option; +use hash::Hash; +use hash::Hasher; /// Types able to be transferred across thread boundaries. #[unstable(feature = "core", @@ -42,7 +46,7 @@ pub unsafe trait Send: 'static { #[lang="send"] #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"] #[cfg(not(stage0))] -pub unsafe trait Send { +pub unsafe trait Send : MarkerTrait { // empty. } @@ -50,7 +54,7 @@ pub unsafe trait Send { #[stable(feature = "rust1", since = "1.0.0")] #[lang="sized"] #[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"] -pub trait Sized { +pub trait Sized : MarkerTrait { // Empty. } @@ -155,7 +159,7 @@ pub trait Sized { /// change: that second example would fail to compile if we made `Foo` non-`Copy`. #[stable(feature = "rust1", since = "1.0.0")] #[lang="copy"] -pub trait Copy { +pub trait Copy : MarkerTrait { // Empty. } @@ -208,216 +212,10 @@ pub trait Copy { reason = "will be overhauled with new lifetime rules; see RFC 458")] #[lang="sync"] #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"] -pub unsafe trait Sync { +pub unsafe trait Sync : MarkerTrait { // Empty } -/// A marker type that indicates to the compiler that the instances -/// of the type itself owns instances of the type parameter `T`. -/// -/// This is used to indicate that one or more instances of the type -/// `T` could be dropped when instances of the type itself is dropped, -/// though that may not be apparent from the other structure of the -/// type itself. For example, the type may hold a `*mut T`, which the -/// compiler does not automatically treat as owned. -#[unstable(feature = "core", - reason = "Newly added to deal with scoping and destructor changes")] -#[lang="phantom_data"] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -pub struct PhantomData; - -impl Copy for PhantomData {} -impl Clone for PhantomData { - fn clone(&self) -> PhantomData { *self } -} - -/// A marker type whose type parameter `T` is considered to be -/// covariant with respect to the type itself. This is (typically) -/// used to indicate that an instance of the type `T` is being stored -/// into memory and read from, even though that may not be apparent. -/// -/// For more information about variance, refer to this Wikipedia -/// article . -/// -/// *Note:* It is very unusual to have to add a covariant constraint. -/// If you are not sure, you probably want to use `InvariantType`. -/// -/// # Example -/// -/// Given a struct `S` that includes a type parameter `T` -/// but does not actually *reference* that type parameter: -/// -/// ```ignore -/// use std::mem; -/// -/// struct S { x: *() } -/// fn get(s: &S) -> T { -/// unsafe { -/// let x: *T = mem::transmute(s.x); -/// *x -/// } -/// } -/// ``` -/// -/// The type system would currently infer that the value of -/// the type parameter `T` is irrelevant, and hence a `S` is -/// a subtype of `S>` (or, for that matter, `S` for -/// any `U`). But this is incorrect because `get()` converts the -/// `*()` into a `*T` and reads from it. Therefore, we should include the -/// a marker field `CovariantType` to inform the type checker that -/// `S` is a subtype of `S` if `T` is a subtype of `U` -/// (for example, `S<&'static int>` is a subtype of `S<&'a int>` -/// for some lifetime `'a`, but not the other way around). -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="covariant_type"] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -pub struct CovariantType; - -impl Copy for CovariantType {} -impl Clone for CovariantType { - fn clone(&self) -> CovariantType { *self } -} - -/// A marker type whose type parameter `T` is considered to be -/// contravariant with respect to the type itself. This is (typically) -/// used to indicate that an instance of the type `T` will be consumed -/// (but not read from), even though that may not be apparent. -/// -/// For more information about variance, refer to this Wikipedia -/// article . -/// -/// *Note:* It is very unusual to have to add a contravariant constraint. -/// If you are not sure, you probably want to use `InvariantType`. -/// -/// # Example -/// -/// Given a struct `S` that includes a type parameter `T` -/// but does not actually *reference* that type parameter: -/// -/// ``` -/// use std::mem; -/// -/// struct S { x: *const () } -/// fn get(s: &S, v: T) { -/// unsafe { -/// let x: fn(T) = mem::transmute(s.x); -/// x(v) -/// } -/// } -/// ``` -/// -/// The type system would currently infer that the value of -/// the type parameter `T` is irrelevant, and hence a `S` is -/// a subtype of `S>` (or, for that matter, `S` for -/// any `U`). But this is incorrect because `get()` converts the -/// `*()` into a `fn(T)` and then passes a value of type `T` to it. -/// -/// Supplying a `ContravariantType` marker would correct the -/// problem, because it would mark `S` so that `S` is only a -/// subtype of `S` if `U` is a subtype of `T`; given that the -/// function requires arguments of type `T`, it must also accept -/// arguments of type `U`, hence such a conversion is safe. -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="contravariant_type"] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -pub struct ContravariantType; - -impl Copy for ContravariantType {} -impl Clone for ContravariantType { - fn clone(&self) -> ContravariantType { *self } -} - -/// A marker type whose type parameter `T` is considered to be -/// invariant with respect to the type itself. This is (typically) -/// used to indicate that instances of the type `T` may be read or -/// written, even though that may not be apparent. -/// -/// For more information about variance, refer to this Wikipedia -/// article . -/// -/// # Example -/// -/// The Cell type is an example of an `InvariantType` which uses unsafe -/// code to achieve "interior" mutability: -/// -/// ``` -/// struct Cell { value: T } -/// ``` -/// -/// The type system would infer that `value` is only read here -/// and never written, but in fact `Cell` uses unsafe code to achieve -/// interior mutability. In order to get correct behavior, the -/// `InvariantType` marker must be applied. -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="invariant_type"] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -pub struct InvariantType; - -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -impl Copy for InvariantType {} -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -impl Clone for InvariantType { - fn clone(&self) -> InvariantType { *self } -} - -/// As `CovariantType`, but for lifetime parameters. Using -/// `CovariantLifetime<'a>` indicates that it is ok to substitute -/// a *longer* lifetime for `'a` than the one you originally -/// started with (e.g., you could convert any lifetime `'foo` to -/// `'static`). You almost certainly want `ContravariantLifetime` -/// instead, or possibly `InvariantLifetime`. The only case where -/// it would be appropriate is that you have a (type-casted, and -/// hence hidden from the type system) function pointer with a -/// signature like `fn(&'a T)` (and no other uses of `'a`). In -/// this case, it is ok to substitute a larger lifetime for `'a` -/// (e.g., `fn(&'static T)`), because the function is only -/// becoming more selective in terms of what it accepts as -/// argument. -/// -/// For more information about variance, refer to this Wikipedia -/// article . -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="covariant_lifetime"] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct CovariantLifetime<'a>; - -/// As `ContravariantType`, but for lifetime parameters. Using -/// `ContravariantLifetime<'a>` indicates that it is ok to -/// substitute a *shorter* lifetime for `'a` than the one you -/// originally started with (e.g., you could convert `'static` to -/// any lifetime `'foo`). This is appropriate for cases where you -/// have an unsafe pointer that is actually a pointer into some -/// memory with lifetime `'a`, and thus you want to limit the -/// lifetime of your data structure to `'a`. An example of where -/// this is used is the iterator for vectors. -/// -/// For more information about variance, refer to this Wikipedia -/// article . -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="contravariant_lifetime"] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct ContravariantLifetime<'a>; - -/// As `InvariantType`, but for lifetime parameters. Using -/// `InvariantLifetime<'a>` indicates that it is not ok to -/// substitute any other lifetime for `'a` besides its original -/// value. This is appropriate for cases where you have an unsafe -/// pointer that is actually a pointer into memory with lifetime `'a`, -/// and this pointer is itself stored in an inherently mutable -/// location (such as a `Cell`). -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="invariant_lifetime"] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct InvariantLifetime<'a>; - /// A type which is considered "not POD", meaning that it is not /// implicitly copyable. This is typically embedded in other types to /// ensure that they are never copied, even if they lack a destructor. @@ -435,6 +233,83 @@ pub struct NoCopy; #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Managed; +macro_rules! impls{ + ($t: ident) => ( + impl Hash for $t { + #[inline] + fn hash(&self, _: &mut S) { + } + } + + impl cmp::PartialEq for $t { + fn eq(&self, _other: &$t) -> bool { + true + } + } + + impl cmp::Eq for $t { + } + + impl cmp::PartialOrd for $t { + fn partial_cmp(&self, _other: &$t) -> Option { + Option::Some(cmp::Ordering::Equal) + } + } + + impl cmp::Ord for $t { + fn cmp(&self, _other: &$t) -> cmp::Ordering { + cmp::Ordering::Equal + } + } + + impl Copy for $t { } + + impl Clone for $t { + fn clone(&self) -> $t { + $t + } + } + ) +} + +/// `MarkerTrait` is intended to be used as the supertrait for traits +/// that don't have any methods but instead serve just to designate +/// categories of types. An example would be the `Send` trait, which +/// indicates types that are sendable: `Send` does not itself offer +/// any methods, but instead is used to gate access to data. +/// +/// FIXME. Better documentation needed here! +pub trait MarkerTrait : PhantomFn { } +impl MarkerTrait for T { } + +/// `PhantomFn` is a marker trait for use with traits that do not +/// include any methods. +/// +/// FIXME. Better documentation needed here! +#[lang="phantom_fn"] +pub trait PhantomFn { } + +#[cfg(stage0)] // built into the trait matching system after stage0 +impl PhantomFn for U { } + +/// Specific to stage0. You should not be seeing these docs! +#[cfg(stage0)] +#[lang="covariant_type"] // only relevant to stage0 +pub struct PhantomData; + +/// `PhantomData` is a way to tell the compiler about fake fields. +/// The idea is that if the compiler encounters a `PhantomData` +/// instance, it will behave *as if* an instance of the type `T` were +/// present for the purpose of various automatic analyses. +/// +/// FIXME. Better documentation needed here! +#[cfg(not(stage0))] +#[lang="phantom_data"] +pub struct PhantomData; + +impls! { PhantomData } + + #[cfg(not(stage0))] mod impls { use super::{Send, Sync, Sized}; diff --git a/src/librustc/middle/infer/bivariate.rs b/src/librustc/middle/infer/bivariate.rs new file mode 100644 index 0000000000000..0589aa03014ad --- /dev/null +++ b/src/librustc/middle/infer/bivariate.rs @@ -0,0 +1,128 @@ +// Copyright 2014 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. + +use middle::ty::{BuiltinBounds}; +use middle::ty::{self, Ty}; +use middle::ty::TyVar; +use middle::infer::combine::*; +use middle::infer::{cres}; +use middle::infer::type_variable::{BiTo}; +use util::ppaux::{Repr}; + +use syntax::ast::{Unsafety}; + +pub struct Bivariate<'f, 'tcx: 'f> { + fields: CombineFields<'f, 'tcx> +} + +#[allow(non_snake_case)] +pub fn Bivariate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Bivariate<'f, 'tcx> { + Bivariate { fields: cf } +} + +impl<'f, 'tcx> Combine<'tcx> for Bivariate<'f, 'tcx> { + fn tag(&self) -> String { "Bivariate".to_string() } + fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields } + + fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + { + match v { + ty::Invariant => self.equate().tys(a, b), + ty::Covariant => self.tys(a, b), + ty::Contravariant => self.tys(a, b), + ty::Bivariant => self.tys(a, b), + } + } + + fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region) + -> cres<'tcx, ty::Region> + { + match v { + ty::Invariant => self.equate().regions(a, b), + ty::Covariant => self.regions(a, b), + ty::Contravariant => self.regions(a, b), + ty::Bivariant => self.regions(a, b), + } + } + + fn regions(&self, a: ty::Region, _: ty::Region) -> cres<'tcx, ty::Region> { + Ok(a) + } + + fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> { + debug!("mts({} <: {})", + a.repr(self.fields.infcx.tcx), + b.repr(self.fields.infcx.tcx)); + + if a.mutbl != b.mutbl { return Err(ty::terr_mutability); } + let t = try!(self.tys(a.ty, b.ty)); + Ok(ty::mt { mutbl: a.mutbl, ty: t }) + } + + fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> { + if a != b { + Err(ty::terr_unsafety_mismatch(expected_found(self, a, b))) + } else { + Ok(a) + } + } + + fn builtin_bounds(&self, + a: BuiltinBounds, + b: BuiltinBounds) + -> cres<'tcx, BuiltinBounds> + { + if a != b { + Err(ty::terr_builtin_bounds(expected_found(self, a, b))) + } else { + Ok(a) + } + } + + fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { + debug!("{}.tys({}, {})", self.tag(), + a.repr(self.fields.infcx.tcx), b.repr(self.fields.infcx.tcx)); + if a == b { return Ok(a); } + + let infcx = self.fields.infcx; + let a = infcx.type_variables.borrow().replace_if_possible(a); + let b = infcx.type_variables.borrow().replace_if_possible(b); + match (&a.sty, &b.sty) { + (&ty::ty_infer(TyVar(a_id)), &ty::ty_infer(TyVar(b_id))) => { + infcx.type_variables.borrow_mut().relate_vars(a_id, BiTo, b_id); + Ok(a) + } + + (&ty::ty_infer(TyVar(a_id)), _) => { + try!(self.fields.instantiate(b, BiTo, a_id)); + Ok(a) + } + + (_, &ty::ty_infer(TyVar(b_id))) => { + try!(self.fields.instantiate(a, BiTo, b_id)); + Ok(a) + } + + _ => { + super_tys(self, a, b) + } + } + } + + fn binders(&self, a: &ty::Binder, b: &ty::Binder) -> cres<'tcx, ty::Binder> + where T : Combineable<'tcx> + { + let a1 = ty::erase_late_bound_regions(self.tcx(), a); + let b1 = ty::erase_late_bound_regions(self.tcx(), b); + let c = try!(Combineable::combine(self, &a1, &b1)); + Ok(ty::Binder(c)) + } +} diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index daa820f43b57e..0eeafb767d8a6 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -32,6 +32,7 @@ // is also useful to track which value is the "expected" value in // terms of error reporting. +use super::bivariate::Bivariate; use super::equate::Equate; use super::glb::Glb; use super::lub::Lub; @@ -39,7 +40,7 @@ use super::sub::Sub; use super::unify::InferCtxtMethodsForSimplyUnifiableTypes; use super::{InferCtxt, cres}; use super::{MiscVariable, TypeTrace}; -use super::type_variable::{RelationDir, EqTo, SubtypeOf, SupertypeOf}; +use super::type_variable::{RelationDir, BiTo, EqTo, SubtypeOf, SupertypeOf}; use middle::subst; use middle::subst::{ErasedRegions, NonerasedRegions, Substs}; @@ -48,7 +49,7 @@ use middle::ty::{IntType, UintType}; use middle::ty::{BuiltinBounds}; use middle::ty::{self, Ty}; use middle::ty_fold; -use middle::ty_fold::{TypeFoldable}; +use middle::ty_fold::{TypeFolder, TypeFoldable}; use util::ppaux::Repr; use std::rc::Rc; @@ -58,41 +59,32 @@ use syntax::abi; use syntax::codemap::Span; pub trait Combine<'tcx> : Sized { - fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx>; fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.infcx().tcx } fn tag(&self) -> String; - fn a_is_expected(&self) -> bool; - fn trace(&self) -> TypeTrace<'tcx>; - fn equate<'a>(&'a self) -> Equate<'a, 'tcx>; - fn sub<'a>(&'a self) -> Sub<'a, 'tcx>; - fn lub<'a>(&'a self) -> Lub<'a, 'tcx>; - fn glb<'a>(&'a self) -> Glb<'a, 'tcx>; + fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx>; + + fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields().infcx } + fn a_is_expected(&self) -> bool { self.fields().a_is_expected } + fn trace(&self) -> TypeTrace<'tcx> { self.fields().trace.clone() } + fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { self.fields().equate() } + fn bivariate<'a>(&'a self) -> Bivariate<'a, 'tcx> { self.fields().bivariate() } + + fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { self.fields().sub() } + fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields().clone()) } + fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields().clone()) } fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>>; - fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>>; + + fn tys_with_variance(&self, variance: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>>; + fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>>; - fn tps(&self, - _: subst::ParamSpace, - as_: &[Ty<'tcx>], - bs: &[Ty<'tcx>]) - -> cres<'tcx, Vec>> { - // FIXME -- In general, we treat variance a bit wrong - // here. For historical reasons, we treat tps and Self - // as invariant. This is overly conservative. - - if as_.len() != bs.len() { - return Err(ty::terr_ty_param_size(expected_found(self, - as_.len(), - bs.len()))); - } + fn regions_with_variance(&self, variance: ty::Variance, a: ty::Region, b: ty::Region) + -> cres<'tcx, ty::Region>; - try!(as_.iter().zip(bs.iter()) - .map(|(a, b)| self.equate().tys(*a, *b)) - .collect::>>()); - Ok(as_.to_vec()) - } + fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region>; fn substs(&self, item_def_id: ast::DefId, @@ -100,6 +92,11 @@ pub trait Combine<'tcx> : Sized { b_subst: &subst::Substs<'tcx>) -> cres<'tcx, subst::Substs<'tcx>> { + debug!("substs: item_def_id={} a_subst={} b_subst={}", + item_def_id.repr(self.infcx().tcx), + a_subst.repr(self.infcx().tcx), + b_subst.repr(self.infcx().tcx)); + let variances = if self.infcx().tcx.variance_computed.get() { Some(ty::item_variances(self.infcx().tcx, item_def_id)) } else { @@ -119,7 +116,8 @@ pub trait Combine<'tcx> : Sized { for &space in &subst::ParamSpace::all() { let a_tps = a_subst.types.get_slice(space); let b_tps = b_subst.types.get_slice(space); - let tps = try!(self.tps(space, a_tps, b_tps)); + let t_variances = variances.map(|v| v.types.get_slice(space)); + let tps = try!(relate_type_params(self, t_variances, a_tps, b_tps)); substs.types.replace(space, tps); } @@ -132,20 +130,7 @@ pub trait Combine<'tcx> : Sized { for &space in &subst::ParamSpace::all() { let a_regions = a.get_slice(space); let b_regions = b.get_slice(space); - - let mut invariance = Vec::new(); - let r_variances = match variances { - Some(variances) => { - variances.regions.get_slice(space) - } - None => { - for _ in a_regions { - invariance.push(ty::Invariant); - } - &invariance[] - } - }; - + let r_variances = variances.map(|v| v.regions.get_slice(space)); let regions = try!(relate_region_params(self, r_variances, a_regions, @@ -157,13 +142,34 @@ pub trait Combine<'tcx> : Sized { return Ok(substs); + fn relate_type_params<'tcx, C: Combine<'tcx>>(this: &C, + variances: Option<&[ty::Variance]>, + a_tys: &[Ty<'tcx>], + b_tys: &[Ty<'tcx>]) + -> cres<'tcx, Vec>> + { + if a_tys.len() != b_tys.len() { + return Err(ty::terr_ty_param_size(expected_found(this, + a_tys.len(), + b_tys.len()))); + } + + range(0, a_tys.len()).map(|i| { + let a_ty = a_tys[i]; + let b_ty = b_tys[i]; + let v = variances.map_or(ty::Invariant, |v| v[i]); + this.tys_with_variance(v, a_ty, b_ty) + }).collect() + } + fn relate_region_params<'tcx, C: Combine<'tcx>>(this: &C, - variances: &[ty::Variance], + variances: Option<&[ty::Variance]>, a_rs: &[ty::Region], b_rs: &[ty::Region]) - -> cres<'tcx, Vec> { + -> cres<'tcx, Vec> + { let tcx = this.infcx().tcx; - let num_region_params = variances.len(); + let num_region_params = a_rs.len(); debug!("relate_region_params(\ a_rs={}, \ @@ -173,22 +179,18 @@ pub trait Combine<'tcx> : Sized { b_rs.repr(tcx), variances.repr(tcx)); - assert_eq!(num_region_params, a_rs.len()); + assert_eq!(num_region_params, + variances.map_or(num_region_params, + |v| v.len())); + assert_eq!(num_region_params, b_rs.len()); - let mut rs = vec!(); - for i in 0..num_region_params { + + (0..a_rs.len()).map(|i| { let a_r = a_rs[i]; let b_r = b_rs[i]; - let variance = variances[i]; - let r = match variance { - ty::Invariant => this.equate().regions(a_r, b_r), - ty::Covariant => this.regions(a_r, b_r), - ty::Contravariant => this.contraregions(a_r, b_r), - ty::Bivariant => Ok(a_r), - }; - rs.push(try!(r)); - } - Ok(rs) + let variance = variances.map_or(ty::Invariant, |v| v[i]); + this.regions_with_variance(variance, a_r, b_r) + }).collect() } } @@ -241,7 +243,7 @@ pub trait Combine<'tcx> : Sized { } fn args(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { - self.contratys(a, b).and_then(|t| Ok(t)) + self.tys_with_variance(ty::Contravariant, a, b).and_then(|t| Ok(t)) } fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety>; @@ -309,7 +311,7 @@ pub trait Combine<'tcx> : Sized { b: &ty::ExistentialBounds<'tcx>) -> cres<'tcx, ty::ExistentialBounds<'tcx>> { - let r = try!(self.contraregions(a.region_bound, b.region_bound)); + let r = try!(self.regions_with_variance(ty::Contravariant, a.region_bound, b.region_bound)); let nb = try!(self.builtin_bounds(a.builtin_bounds, b.builtin_bounds)); let pb = try!(self.projection_bounds(&a.projection_bounds, &b.projection_bounds)); Ok(ty::ExistentialBounds { region_bound: r, @@ -322,11 +324,6 @@ pub trait Combine<'tcx> : Sized { b: ty::BuiltinBounds) -> cres<'tcx, ty::BuiltinBounds>; - fn contraregions(&self, a: ty::Region, b: ty::Region) - -> cres<'tcx, ty::Region>; - - fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region>; - fn trait_refs(&self, a: &ty::TraitRef<'tcx>, b: &ty::TraitRef<'tcx>) @@ -540,7 +537,8 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, } (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => { - let r = try!(this.contraregions(*a_r, *b_r)); + let r = try!(this.regions_with_variance(ty::Contravariant, *a_r, *b_r)); + // FIXME(14985) If we have mutable references to trait objects, we // used to use covariant subtyping. I have preserved this behaviour, // even though it is probably incorrect. So don't go down the usual @@ -644,6 +642,10 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { Equate((*self).clone()) } + fn bivariate(&self) -> Bivariate<'f, 'tcx> { + Bivariate((*self).clone()) + } + fn sub(&self) -> Sub<'f, 'tcx> { Sub((*self).clone()) } @@ -697,7 +699,7 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { EqTo => { self.generalize(a_ty, b_vid, false) } - SupertypeOf | SubtypeOf => { + BiTo | SupertypeOf | SubtypeOf => { self.generalize(a_ty, b_vid, true) } }); @@ -721,6 +723,10 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { // to associate causes/spans with each of the relations in // the stack to get this right. match dir { + BiTo => { + try!(self.bivariate().tys(a_ty, b_ty)); + } + EqTo => { try!(self.equate().tys(a_ty, b_ty)); } @@ -730,7 +736,7 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { } SupertypeOf => { - try!(self.sub().contratys(a_ty, b_ty)); + try!(self.sub().tys_with_variance(ty::Contravariant, a_ty, b_ty)); } } } diff --git a/src/librustc/middle/infer/equate.rs b/src/librustc/middle/infer/equate.rs index f0bde22286488..7194e20b0cf65 100644 --- a/src/librustc/middle/infer/equate.rs +++ b/src/librustc/middle/infer/equate.rs @@ -13,11 +13,7 @@ use middle::ty::{self, Ty}; use middle::ty::TyVar; use middle::infer::combine::*; use middle::infer::{cres}; -use middle::infer::glb::Glb; -use middle::infer::InferCtxt; -use middle::infer::lub::Lub; -use middle::infer::sub::Sub; -use middle::infer::{TypeTrace, Subtype}; +use middle::infer::{Subtype}; use middle::infer::type_variable::{EqTo}; use util::ppaux::{Repr}; @@ -33,21 +29,20 @@ pub fn Equate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Equate<'f, 'tcx> { } impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> { - fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx } - fn tag(&self) -> String { "eq".to_string() } - fn a_is_expected(&self) -> bool { self.fields.a_is_expected } - fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() } + fn tag(&self) -> String { "Equate".to_string() } + fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields } - fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) } - fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) } - fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) } - fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) } - - fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { + fn tys_with_variance(&self, _: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + { + // Once we're equating, it doesn't matter what the variance is. self.tys(a, b) } - fn contraregions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> { + fn regions_with_variance(&self, _: ty::Variance, a: ty::Region, b: ty::Region) + -> cres<'tcx, ty::Region> + { + // Once we're equating, it doesn't matter what the variance is. self.regions(a, b) } diff --git a/src/librustc/middle/infer/glb.rs b/src/librustc/middle/infer/glb.rs index ff0c2d92f45ee..33303808e8491 100644 --- a/src/librustc/middle/infer/glb.rs +++ b/src/librustc/middle/infer/glb.rs @@ -10,12 +10,9 @@ use super::combine::*; use super::lattice::*; -use super::equate::Equate; use super::higher_ranked::HigherRankedRelations; -use super::lub::Lub; -use super::sub::Sub; -use super::{cres, InferCtxt}; -use super::{TypeTrace, Subtype}; +use super::{cres}; +use super::Subtype; use middle::ty::{BuiltinBounds}; use middle::ty::{self, Ty}; @@ -34,15 +31,30 @@ pub fn Glb<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Glb<'f, 'tcx> { } impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> { - fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx } - fn tag(&self) -> String { "glb".to_string() } - fn a_is_expected(&self) -> bool { self.fields.a_is_expected } - fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() } + fn tag(&self) -> String { "Glb".to_string() } + fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields } - fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) } - fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) } - fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) } - fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) } + fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + { + match v { + ty::Invariant => self.equate().tys(a, b), + ty::Covariant => self.tys(a, b), + ty::Bivariant => self.bivariate().tys(a, b), + ty::Contravariant => self.lub().tys(a, b), + } + } + + fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region) + -> cres<'tcx, ty::Region> + { + match v { + ty::Invariant => self.equate().regions(a, b), + ty::Covariant => self.regions(a, b), + ty::Bivariant => self.bivariate().regions(a, b), + ty::Contravariant => self.lub().regions(a, b), + } + } fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> { let tcx = self.fields.infcx.tcx; @@ -75,10 +87,6 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> { } } - fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { - self.lub().tys(a, b) - } - fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> { match (a, b) { (Unsafety::Normal, _) | (_, Unsafety::Normal) => Ok(Unsafety::Normal), @@ -104,11 +112,6 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> { Ok(self.fields.infcx.region_vars.glb_regions(Subtype(self.trace()), a, b)) } - fn contraregions(&self, a: ty::Region, b: ty::Region) - -> cres<'tcx, ty::Region> { - self.lub().regions(a, b) - } - fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { super_lattice_tys(self, a, b) } diff --git a/src/librustc/middle/infer/lub.rs b/src/librustc/middle/infer/lub.rs index 204560e87ee3b..3570effa9fa70 100644 --- a/src/librustc/middle/infer/lub.rs +++ b/src/librustc/middle/infer/lub.rs @@ -9,13 +9,10 @@ // except according to those terms. use super::combine::*; -use super::equate::Equate; -use super::glb::Glb; use super::higher_ranked::HigherRankedRelations; use super::lattice::*; -use super::sub::Sub; -use super::{cres, InferCtxt}; -use super::{TypeTrace, Subtype}; +use super::{cres}; +use super::{Subtype}; use middle::ty::{BuiltinBounds}; use middle::ty::{self, Ty}; @@ -34,15 +31,30 @@ pub fn Lub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Lub<'f, 'tcx> { } impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> { - fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx } - fn tag(&self) -> String { "lub".to_string() } - fn a_is_expected(&self) -> bool { self.fields.a_is_expected } - fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() } + fn tag(&self) -> String { "Lub".to_string() } + fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields } - fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) } - fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) } - fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) } - fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) } + fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + { + match v { + ty::Invariant => self.equate().tys(a, b), + ty::Covariant => self.tys(a, b), + ty::Bivariant => self.bivariate().tys(a, b), + ty::Contravariant => self.glb().tys(a, b), + } + } + + fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region) + -> cres<'tcx, ty::Region> + { + match v { + ty::Invariant => self.equate().regions(a, b), + ty::Covariant => self.regions(a, b), + ty::Bivariant => self.bivariate().regions(a, b), + ty::Contravariant => self.glb().regions(a, b), + } + } fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> { let tcx = self.tcx(); @@ -70,10 +82,6 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> { } } - fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { - self.glb().tys(a, b) - } - fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> { match (a, b) { (Unsafety::Unsafe, _) | (_, Unsafety::Unsafe) => Ok(Unsafety::Unsafe), @@ -90,11 +98,6 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> { Ok(a.intersection(b)) } - fn contraregions(&self, a: ty::Region, b: ty::Region) - -> cres<'tcx, ty::Region> { - self.glb().regions(a, b) - } - fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> { debug!("{}.regions({}, {})", self.tag(), diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 00e377d65fea7..3cffe4c0fda40 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -45,6 +45,7 @@ use self::lub::Lub; use self::unify::{UnificationTable, InferCtxtMethodsForSimplyUnifiableTypes}; use self::error_reporting::ErrorReporting; +pub mod bivariate; pub mod combine; pub mod equate; pub mod error_reporting; diff --git a/src/librustc/middle/infer/sub.rs b/src/librustc/middle/infer/sub.rs index 1e0d14544ff88..bfe5ba4c4c5d2 100644 --- a/src/librustc/middle/infer/sub.rs +++ b/src/librustc/middle/infer/sub.rs @@ -10,12 +10,8 @@ use super::combine::*; use super::{cres, CresCompare}; -use super::equate::Equate; -use super::glb::Glb; use super::higher_ranked::HigherRankedRelations; -use super::InferCtxt; -use super::lub::Lub; -use super::{TypeTrace, Subtype}; +use super::{Subtype}; use super::type_variable::{SubtypeOf, SupertypeOf}; use middle::ty::{BuiltinBounds}; @@ -37,28 +33,31 @@ pub fn Sub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Sub<'f, 'tcx> { } impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> { - fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx } - fn tag(&self) -> String { "sub".to_string() } - fn a_is_expected(&self) -> bool { self.fields.a_is_expected } - fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() } - - fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) } - fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) } - fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) } - fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) } - - fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { - Sub(self.fields.switch_expected()).tys(b, a) + fn tag(&self) -> String { "Sub".to_string() } + fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields } + + fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + { + // Once we're equating, it doesn't matter what the variance is. + match v { + ty::Invariant => self.equate().tys(a, b), + ty::Covariant => self.tys(a, b), + ty::Bivariant => self.bivariate().tys(a, b), + ty::Contravariant => Sub(self.fields.switch_expected()).tys(b, a), + } } - fn contraregions(&self, a: ty::Region, b: ty::Region) - -> cres<'tcx, ty::Region> { - let opp = CombineFields { - a_is_expected: !self.fields.a_is_expected, - ..self.fields.clone() - }; - Sub(opp).regions(b, a) - } + fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region) + -> cres<'tcx, ty::Region> + { + match v { + ty::Invariant => self.equate().regions(a, b), + ty::Covariant => self.regions(a, b), + ty::Bivariant => self.bivariate().regions(a, b), + ty::Contravariant => Sub(self.fields.switch_expected()).regions(b, a), + } + } fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> { debug!("{}.regions({}, {})", diff --git a/src/librustc/middle/infer/type_variable.rs b/src/librustc/middle/infer/type_variable.rs index 9b8a4a844120d..4b9718b4f6ce7 100644 --- a/src/librustc/middle/infer/type_variable.rs +++ b/src/librustc/middle/infer/type_variable.rs @@ -48,7 +48,7 @@ type Relation = (RelationDir, ty::TyVid); #[derive(Copy, PartialEq, Debug)] pub enum RelationDir { - SubtypeOf, SupertypeOf, EqTo + SubtypeOf, SupertypeOf, EqTo, BiTo } impl RelationDir { @@ -56,7 +56,8 @@ impl RelationDir { match self { SubtypeOf => SupertypeOf, SupertypeOf => SubtypeOf, - EqTo => EqTo + EqTo => EqTo, + BiTo => BiTo, } } } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index e13a5672778e2..acebb97a0c13f 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -312,16 +312,9 @@ lets_do_this! { ExchangeHeapLangItem, "exchange_heap", exchange_heap; OwnedBoxLangItem, "owned_box", owned_box; + PhantomFnItem, "phantom_fn", phantom_fn; PhantomDataItem, "phantom_data", phantom_data; - CovariantTypeItem, "covariant_type", covariant_type; - ContravariantTypeItem, "contravariant_type", contravariant_type; - InvariantTypeItem, "invariant_type", invariant_type; - - CovariantLifetimeItem, "covariant_lifetime", covariant_lifetime; - ContravariantLifetimeItem, "contravariant_lifetime", contravariant_lifetime; - InvariantLifetimeItem, "invariant_lifetime", invariant_lifetime; - NoCopyItem, "no_copy_bound", no_copy_bound; ManagedItem, "managed_bound", managed_bound; diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 061557eb7dccd..ac8f7783eb82b 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -133,6 +133,7 @@ pub enum MethodMatchedData { /// parameters) that would have to be inferred from the impl. #[derive(PartialEq,Eq,Debug,Clone)] enum SelectionCandidate<'tcx> { + PhantomFnCandidate, BuiltinCandidate(ty::BuiltinBound), ParamCandidate(ty::PolyTraitRef<'tcx>), ImplCandidate(ast::DefId), @@ -795,8 +796,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { stack: &TraitObligationStack<'o, 'tcx>) -> Result, SelectionError<'tcx>> { - // Check for overflow. - let TraitObligationStack { obligation, .. } = *stack; let mut candidates = SelectionCandidateSet { @@ -804,6 +803,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ambiguous: false }; + // Check for the `PhantomFn` trait. This is really just a special annotation that + // *always* be considered to match, no matter what the type parameters etc. + if self.tcx().lang_items.phantom_fn() == Some(obligation.predicate.def_id()) { + candidates.vec.push(PhantomFnCandidate); + return Ok(candidates); + } + // Other bounds. Consider both in-scope bounds from fn decl // and applicable impls. There is a certain set of precedence rules here. @@ -1673,6 +1679,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { try!(self.confirm_builtin_candidate(obligation, builtin_bound)))) } + PhantomFnCandidate | ErrorCandidate => { Ok(VtableBuiltin(VtableBuiltinData { nested: VecPerParamSpace::empty() })) } @@ -2339,6 +2346,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> { fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { match *self { + PhantomFnCandidate => format!("PhantomFnCandidate"), ErrorCandidate => format!("ErrorCandidate"), BuiltinCandidate(b) => format!("BuiltinCandidate({:?})", b), ParamCandidate(ref a) => format!("ParamCandidate({})", a.repr(tcx)), diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs new file mode 100644 index 0000000000000..f40add8e2c0ab --- /dev/null +++ b/src/librustc_typeck/constrained_type_params.rs @@ -0,0 +1,61 @@ +// Copyright 2015 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. + +use middle::ty::{self}; + +use std::collections::HashSet; +use std::rc::Rc; + +pub fn identify_constrained_type_params<'tcx>(_tcx: &ty::ctxt<'tcx>, + predicates: &[ty::Predicate<'tcx>], + impl_trait_ref: Option>>, + input_parameters: &mut HashSet) +{ + loop { + let num_inputs = input_parameters.len(); + + let projection_predicates = + predicates.iter() + .filter_map(|predicate| { + match *predicate { + // Ignore higher-ranked binders. For the purposes + // of this check, they don't matter because they + // only affect named regions, and we're just + // concerned about type parameters here. + ty::Predicate::Projection(ref data) => Some(data.0.clone()), + _ => None, + } + }); + + for projection in projection_predicates { + // Special case: watch out for some kind of sneaky attempt + // to project out an associated type defined by this very trait. + if Some(projection.projection_ty.trait_ref.clone()) == impl_trait_ref { + continue; + } + + let relies_only_on_inputs = + projection.projection_ty.trait_ref.input_types() + .iter() + .flat_map(|t| t.walk()) + .filter_map(|t| t.as_opt_param_ty()) + .all(|t| input_parameters.contains(&t)); + + if relies_only_on_inputs { + input_parameters.extend( + projection.ty.walk().filter_map(|t| t.as_opt_param_ty())); + } + } + + if input_parameters.len() == num_inputs { + break; + } + } +} diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index d5883d8bf864b..be7138d54f8d0 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -187,6 +187,22 @@ //! and the definition-site variance of the [corresponding] type parameter //! of a class `C` is `V1`, then the variance of `X` in the type expression //! `C` is `V3 = V1.xform(V2)`. +//! +//! ### Constraints +//! +//! If I have a struct or enum with where clauses: +//! +//! struct Foo { ... } +//! +//! you might wonder whether the variance of `T` with respect to `Bar` +//! affects the variance `T` with respect to `Foo`. I claim no. The +//! reason: assume that `T` is invariant w/r/t `Bar` but covariant w/r/t +//! `Foo`. And then we have a `Foo` that is upcast to `Foo`, where +//! `X <: Y`. However, while `X : Bar`, `Y : Bar` does not hold. In that +//! case, the upcast will be illegal, but not because of a variance +//! failure, but rather because the target type `Foo` is itself just +//! not well-formed. Basically we get to assume well-formedness of all +//! types involved before considering variance. use self::VarianceTerm::*; use self::ParamKind::*; @@ -199,7 +215,6 @@ use middle::subst::{ParamSpace, FnSpace, TypeSpace, SelfSpace, VecPerParamSpace} use middle::ty::{self, Ty}; use std::fmt; use std::rc::Rc; -use std::iter::repeat; use syntax::ast; use syntax::ast_map; use syntax::ast_util; @@ -258,6 +273,11 @@ struct TermsContext<'a, 'tcx: 'a> { empty_variances: Rc, + // For marker types, UnsafeCell, and other lang items where + // variance is hardcoded, records the item-id and the hardcoded + // variance. + lang_items: Vec<(ast::NodeId, Vec)>, + // Maps from the node id of a type/generic parameter to the // corresponding inferred index. inferred_map: NodeMap, @@ -269,7 +289,7 @@ struct TermsContext<'a, 'tcx: 'a> { #[derive(Copy, Debug, PartialEq)] enum ParamKind { TypeParam, - RegionParam + RegionParam, } struct InferredInfo<'a> { @@ -279,6 +299,11 @@ struct InferredInfo<'a> { index: uint, param_id: ast::NodeId, term: VarianceTermPtr<'a>, + + // Initial value to use for this parameter when inferring + // variance. For most parameters, this is Bivariant. But for lang + // items and input type parameters on traits, it is different. + initial_variance: ty::Variance, } fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, @@ -291,6 +316,8 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, inferred_map: NodeMap(), inferred_infos: Vec::new(), + lang_items: lang_items(tcx), + // cache and share the variance struct used for items with // no type/region parameters empty_variances: Rc::new(ty::ItemVariances { @@ -304,7 +331,68 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, terms_cx } +fn lang_items(tcx: &ty::ctxt) -> Vec<(ast::NodeId,Vec)> { + let all = vec![ + (tcx.lang_items.phantom_fn(), vec![ty::Contravariant, ty::Covariant]), + (tcx.lang_items.phantom_data(), vec![ty::Covariant]), + (tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant])]; + + all.into_iter() + .filter(|&(ref d,_)| d.is_some()) + .filter(|&(ref d,_)| d.as_ref().unwrap().krate == ast::LOCAL_CRATE) + .map(|(d, v)| (d.unwrap().node, v)) + .collect() +} + impl<'a, 'tcx> TermsContext<'a, 'tcx> { + fn add_inferreds_for_item(&mut self, + item_id: ast::NodeId, + has_self: bool, + generics: &ast::Generics) + { + /*! + * Add "inferreds" for the generic parameters declared on this + * item. This has a lot of annoying parameters because we are + * trying to drive this from the AST, rather than the + * ty::Generics, so that we can get span info -- but this + * means we must accommodate syntactic distinctions. + */ + + // NB: In the code below for writing the results back into the + // tcx, we rely on the fact that all inferreds for a particular + // item are assigned continuous indices. + + let inferreds_on_entry = self.num_inferred(); + + if has_self { + self.add_inferred(item_id, TypeParam, SelfSpace, 0, item_id); + } + + for (i, p) in generics.lifetimes.iter().enumerate() { + let id = p.lifetime.id; + self.add_inferred(item_id, RegionParam, TypeSpace, i, id); + } + + for (i, p) in generics.ty_params.iter().enumerate() { + self.add_inferred(item_id, TypeParam, TypeSpace, i, p.id); + } + + // If this item has no type or lifetime parameters, + // then there are no variances to infer, so just + // insert an empty entry into the variance map. + // Arguably we could just leave the map empty in this + // case but it seems cleaner to be able to distinguish + // "invalid item id" from "item id with no + // parameters". + if self.num_inferred() == inferreds_on_entry { + let newly_added = + self.tcx.item_variance_map.borrow_mut().insert( + ast_util::local_def(item_id), + self.empty_variances.clone()).is_none(); + assert!(newly_added); + } + } + fn add_inferred(&mut self, item_id: ast::NodeId, kind: ParamKind, @@ -313,21 +401,48 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> { param_id: ast::NodeId) { let inf_index = InferredIndex(self.inferred_infos.len()); let term = self.arena.alloc(InferredTerm(inf_index)); + let initial_variance = self.pick_initial_variance(item_id, space, index); self.inferred_infos.push(InferredInfo { item_id: item_id, kind: kind, space: space, index: index, param_id: param_id, - term: term }); + term: term, + initial_variance: initial_variance }); let newly_added = self.inferred_map.insert(param_id, inf_index).is_none(); assert!(newly_added); - debug!("add_inferred(item_id={}, \ + debug!("add_inferred(item_path={}, \ + item_id={}, \ kind={:?}, \ + space={:?}, \ index={}, \ - param_id={}, - inf_index={:?})", - item_id, kind, index, param_id, inf_index); + param_id={}, \ + inf_index={:?}, \ + initial_variance={:?})", + ty::item_path_str(self.tcx, ast_util::local_def(item_id)), + item_id, kind, space, index, param_id, inf_index, + initial_variance); + } + + fn pick_initial_variance(&self, + item_id: ast::NodeId, + space: ParamSpace, + index: uint) + -> ty::Variance + { + match space { + SelfSpace | FnSpace => { + ty::Bivariant + } + + TypeSpace => { + match self.lang_items.iter().find(|&&(n, _)| n == item_id) { + Some(&(_, ref variances)) => variances[index], + None => ty::Bivariant + } + } + } } fn num_inferred(&self) -> uint { @@ -339,44 +454,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> { fn visit_item(&mut self, item: &ast::Item) { debug!("add_inferreds for item {}", item.repr(self.tcx)); - let inferreds_on_entry = self.num_inferred(); - - // NB: In the code below for writing the results back into the - // tcx, we rely on the fact that all inferreds for a particular - // item are assigned continuous indices. - match item.node { - ast::ItemTrait(..) => { - self.add_inferred(item.id, TypeParam, SelfSpace, 0, item.id); - } - _ => { } - } - match item.node { ast::ItemEnum(_, ref generics) | - ast::ItemStruct(_, ref generics) | + ast::ItemStruct(_, ref generics) => { + self.add_inferreds_for_item(item.id, false, generics); + } ast::ItemTrait(_, ref generics, _, _) => { - for (i, p) in generics.lifetimes.iter().enumerate() { - let id = p.lifetime.id; - self.add_inferred(item.id, RegionParam, TypeSpace, i, id); - } - for (i, p) in generics.ty_params.iter().enumerate() { - self.add_inferred(item.id, TypeParam, TypeSpace, i, p.id); - } - - // If this item has no type or lifetime parameters, - // then there are no variances to infer, so just - // insert an empty entry into the variance map. - // Arguably we could just leave the map empty in this - // case but it seems cleaner to be able to distinguish - // "invalid item id" from "item id with no - // parameters". - if self.num_inferred() == inferreds_on_entry { - let newly_added = self.tcx.item_variance_map.borrow_mut().insert( - ast_util::local_def(item.id), - self.empty_variances.clone()).is_none(); - assert!(newly_added); - } - + self.add_inferreds_for_item(item.id, true, generics); visit::walk_item(self, item); } @@ -404,16 +488,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> { struct ConstraintContext<'a, 'tcx: 'a> { terms_cx: TermsContext<'a, 'tcx>, - // These are the def-id of the std::marker::InvariantType, - // std::marker::InvariantLifetime, and so on. The arrays - // are indexed by the `ParamKind` (type, lifetime, self). Note - // that there are no marker types for self, so the entries for - // self are always None. - invariant_lang_items: [Option; 2], - covariant_lang_items: [Option; 2], - contravariant_lang_items: [Option; 2], - unsafe_cell_lang_item: Option, - // These are pointers to common `ConstantTerm` instances covariant: VarianceTermPtr<'a>, contravariant: VarianceTermPtr<'a>, @@ -433,40 +507,14 @@ struct Constraint<'a> { fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>, krate: &ast::Crate) - -> ConstraintContext<'a, 'tcx> { - let mut invariant_lang_items = [None; 2]; - let mut covariant_lang_items = [None; 2]; - let mut contravariant_lang_items = [None; 2]; - - covariant_lang_items[TypeParam as uint] = - terms_cx.tcx.lang_items.covariant_type(); - covariant_lang_items[RegionParam as uint] = - terms_cx.tcx.lang_items.covariant_lifetime(); - - contravariant_lang_items[TypeParam as uint] = - terms_cx.tcx.lang_items.contravariant_type(); - contravariant_lang_items[RegionParam as uint] = - terms_cx.tcx.lang_items.contravariant_lifetime(); - - invariant_lang_items[TypeParam as uint] = - terms_cx.tcx.lang_items.invariant_type(); - invariant_lang_items[RegionParam as uint] = - terms_cx.tcx.lang_items.invariant_lifetime(); - - let unsafe_cell_lang_item = terms_cx.tcx.lang_items.unsafe_cell_type(); - + -> ConstraintContext<'a, 'tcx> +{ let covariant = terms_cx.arena.alloc(ConstantTerm(ty::Covariant)); let contravariant = terms_cx.arena.alloc(ConstantTerm(ty::Contravariant)); let invariant = terms_cx.arena.alloc(ConstantTerm(ty::Invariant)); let bivariant = terms_cx.arena.alloc(ConstantTerm(ty::Bivariant)); let mut constraint_cx = ConstraintContext { terms_cx: terms_cx, - - invariant_lang_items: invariant_lang_items, - covariant_lang_items: covariant_lang_items, - contravariant_lang_items: contravariant_lang_items, - unsafe_cell_lang_item: unsafe_cell_lang_item, - covariant: covariant, contravariant: contravariant, invariant: invariant, @@ -487,7 +535,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { match item.node { ast::ItemEnum(ref enum_definition, _) => { - let generics = &ty::lookup_item_type(tcx, did).generics; + let scheme = ty::lookup_item_type(tcx, did); + + // Not entirely obvious: constraints on structs/enums do not + // affect the variance of their type parameters. See discussion + // in comment at top of module. + // + // self.add_constraints_from_generics(&scheme.generics); // Hack: If we directly call `ty::enum_variants`, it // annoyingly takes it upon itself to run off and @@ -505,29 +559,48 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { &**ast_variant, /*discriminant*/ 0); for arg_ty in &variant.args { - self.add_constraints_from_ty(generics, *arg_ty, self.covariant); + self.add_constraints_from_ty(&scheme.generics, *arg_ty, self.covariant); } } } ast::ItemStruct(..) => { - let generics = &ty::lookup_item_type(tcx, did).generics; + let scheme = ty::lookup_item_type(tcx, did); + + // Not entirely obvious: constraints on structs/enums do not + // affect the variance of their type parameters. See discussion + // in comment at top of module. + // + // self.add_constraints_from_generics(&scheme.generics); + let struct_fields = ty::lookup_struct_fields(tcx, did); for field_info in &struct_fields { assert_eq!(field_info.id.krate, ast::LOCAL_CRATE); let field_ty = ty::node_id_to_type(tcx, field_info.id.node); - self.add_constraints_from_ty(generics, field_ty, self.covariant); + self.add_constraints_from_ty(&scheme.generics, field_ty, self.covariant); } } ast::ItemTrait(..) => { + let trait_def = ty::lookup_trait_def(tcx, did); + let predicates = ty::predicates(tcx, ty::mk_self_type(tcx), &trait_def.bounds); + self.add_constraints_from_predicates(&trait_def.generics, + &predicates[], + self.covariant); + let trait_items = ty::trait_items(tcx, did); for trait_item in &*trait_items { match *trait_item { ty::MethodTraitItem(ref method) => { - self.add_constraints_from_sig(&method.generics, - &method.fty.sig, - self.covariant); + self.add_constraints_from_predicates( + &method.generics, + method.predicates.predicates.get_slice(FnSpace), + self.contravariant); + + self.add_constraints_from_sig( + &method.generics, + &method.fty.sig, + self.covariant); } ty::TypeTraitItem(_) => {} } @@ -544,9 +617,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { ast::ItemTy(..) | ast::ItemImpl(..) | ast::ItemMac(..) => { - visit::walk_item(self, item); } } + + visit::walk_item(self, item); } } @@ -648,15 +722,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { -> VarianceTermPtr<'a> { assert_eq!(param_def_id.krate, item_def_id.krate); - if self.invariant_lang_items[kind as uint] == Some(item_def_id) { - self.invariant - } else if self.covariant_lang_items[kind as uint] == Some(item_def_id) { - self.covariant - } else if self.contravariant_lang_items[kind as uint] == Some(item_def_id) { - self.contravariant - } else if kind == TypeParam && Some(item_def_id) == self.unsafe_cell_lang_item { - self.invariant - } else if param_def_id.krate == ast::LOCAL_CRATE { + if param_def_id.krate == ast::LOCAL_CRATE { // Parameter on an item defined within current crate: // variance not yet inferred, so return a symbolic // variance. @@ -724,6 +790,25 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } } + fn add_constraints_from_trait_ref(&mut self, + generics: &ty::Generics<'tcx>, + trait_ref: &ty::TraitRef<'tcx>, + variance: VarianceTermPtr<'a>) { + debug!("add_constraints_from_trait_ref: trait_ref={} variance={:?}", + trait_ref.repr(self.tcx()), + variance); + + let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id); + + self.add_constraints_from_substs( + generics, + trait_ref.def_id, + trait_def.generics.types.as_slice(), + trait_def.generics.regions.as_slice(), + trait_ref.substs, + variance); + } + /// Adds constraints appropriate for an instance of `ty` appearing /// in a context with the generics defined in `generics` and /// ambient variance `variance` @@ -731,7 +816,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { generics: &ty::Generics<'tcx>, ty: Ty<'tcx>, variance: VarianceTermPtr<'a>) { - debug!("add_constraints_from_ty(ty={})", ty.repr(self.tcx())); + debug!("add_constraints_from_ty(ty={}, variance={:?})", + ty.repr(self.tcx()), + variance); match ty.sty { ty::ty_bool | @@ -754,6 +841,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_ty(generics, typ, variance); } + ty::ty_ptr(ref mt) => { self.add_constraints_from_mt(generics, mt, variance); } @@ -797,27 +885,16 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } ty::ty_trait(ref data) => { - let trait_ref = data.principal_trait_ref_with_self_ty(self.tcx(), - self.tcx().types.err); - let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id()); - - // Traits never declare region parameters in the self - // space nor anything in the fn space. - assert!(trait_def.generics.regions.is_empty_in(subst::SelfSpace)); - assert!(trait_def.generics.types.is_empty_in(subst::FnSpace)); - assert!(trait_def.generics.regions.is_empty_in(subst::FnSpace)); + let poly_trait_ref = + data.principal_trait_ref_with_self_ty(self.tcx(), + self.tcx().types.err); // The type `Foo` is contravariant w/r/t `'a`: let contra = self.contravariant(variance); self.add_constraints_from_region(generics, data.bounds.region_bound, contra); - self.add_constraints_from_substs( - generics, - trait_ref.def_id(), - trait_def.generics.types.get_slice(subst::TypeSpace), - trait_def.generics.regions.get_slice(subst::TypeSpace), - trait_ref.substs(), - variance); + // Ignore the SelfSpace, it is erased. + self.add_constraints_from_trait_ref(generics, &*poly_trait_ref.0, variance); let projections = data.projection_bounds_with_self_ty(self.tcx(), self.tcx().types.err); @@ -845,7 +922,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_sig(generics, sig, variance); } - ty::ty_infer(..) | ty::ty_err => { + ty::ty_err => { + // we encounter this when walking the trait references for object + // types, where we use ty_err as the Self type + } + + ty::ty_infer(..) => { self.tcx().sess.bug( &format!("unexpected type encountered in \ variance inference: {}", @@ -864,7 +946,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { region_param_defs: &[ty::RegionParameterDef], substs: &subst::Substs<'tcx>, variance: VarianceTermPtr<'a>) { - debug!("add_constraints_from_substs(def_id={:?})", def_id); + debug!("add_constraints_from_substs(def_id={}, substs={}, variance={:?})", + def_id.repr(self.tcx()), + substs.repr(self.tcx()), + variance); for p in type_param_defs { let variance_decl = @@ -872,6 +957,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { p.space, p.index as uint); let variance_i = self.xform(variance, variance_decl); let substs_ty = *substs.types.get(p.space, p.index as uint); + debug!("add_constraints_from_substs: variance_decl={:?} variance_i={:?}", + variance_decl, variance_i); self.add_constraints_from_ty(generics, substs_ty, variance_i); } @@ -885,6 +972,51 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } } + fn add_constraints_from_predicates(&mut self, + generics: &ty::Generics<'tcx>, + predicates: &[ty::Predicate<'tcx>], + variance: VarianceTermPtr<'a>) { + debug!("add_constraints_from_generics({})", + generics.repr(self.tcx())); + + for predicate in predicates.iter() { + match *predicate { + ty::Predicate::Trait(ty::Binder(ref data)) => { + self.add_constraints_from_trait_ref(generics, &*data.trait_ref, variance); + } + + ty::Predicate::Equate(ty::Binder(ref data)) => { + self.add_constraints_from_ty(generics, data.0, variance); + self.add_constraints_from_ty(generics, data.1, variance); + } + + ty::Predicate::TypeOutlives(ty::Binder(ref data)) => { + self.add_constraints_from_ty(generics, data.0, variance); + + let variance_r = self.xform(variance, self.contravariant); + self.add_constraints_from_region(generics, data.1, variance_r); + } + + ty::Predicate::RegionOutlives(ty::Binder(ref data)) => { + // `'a : 'b` is still true if 'a gets bigger + self.add_constraints_from_region(generics, data.0, variance); + + // `'a : 'b` is still true if 'b gets smaller + let variance_r = self.xform(variance, self.contravariant); + self.add_constraints_from_region(generics, data.1, variance_r); + } + + ty::Predicate::Projection(ty::Binder(ref data)) => { + self.add_constraints_from_trait_ref(generics, + &*data.projection_ty.trait_ref, + variance); + + self.add_constraints_from_ty(generics, data.ty, self.invariant); + } + } + } + } + /// Adds constraints appropriate for a function with signature /// `sig` appearing in a context with ambient variance `variance` fn add_constraints_from_sig(&mut self, @@ -969,7 +1101,12 @@ struct SolveContext<'a, 'tcx: 'a> { fn solve_constraints(constraints_cx: ConstraintContext) { let ConstraintContext { terms_cx, constraints, .. } = constraints_cx; - let solutions: Vec<_> = repeat(ty::Bivariant).take(terms_cx.num_inferred()).collect(); + + let solutions = + terms_cx.inferred_infos.iter() + .map(|ii| ii.initial_variance) + .collect(); + let mut solutions_cx = SolveContext { terms_cx: terms_cx, constraints: constraints, @@ -1034,20 +1171,16 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { let mut types = VecPerParamSpace::empty(); let mut regions = VecPerParamSpace::empty(); - while index < num_inferred && - inferred_infos[index].item_id == item_id { + while index < num_inferred && inferred_infos[index].item_id == item_id { let info = &inferred_infos[index]; let variance = solutions[index]; debug!("Index {} Info {} / {:?} / {:?} Variance {:?}", index, info.index, info.kind, info.space, variance); match info.kind { - TypeParam => { - types.push(info.space, variance); - } - RegionParam => { - regions.push(info.space, variance); - } + TypeParam => { types.push(info.space, variance); } + RegionParam => { regions.push(info.space, variance); } } + index += 1; } @@ -1144,3 +1277,4 @@ fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance { (x, ty::Bivariant) | (ty::Bivariant, x) => x, } } + diff --git a/src/test/compile-fail/variance-contravariant-arg-object.rs b/src/test/compile-fail/variance-contravariant-arg-object.rs new file mode 100644 index 0000000000000..3330e1d0d51b0 --- /dev/null +++ b/src/test/compile-fail/variance-contravariant-arg-object.rs @@ -0,0 +1,31 @@ +// Copyright 2015 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. + +#![allow(dead_code)] + +trait Get : 'static { + fn get(&self, t: T); +} + +fn get_min_from_max<'min, 'max>(v: Box>) + -> Box> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +fn get_max_from_min<'min, 'max, G>(v: Box>) + -> Box> + where 'max : 'min +{ + v +} + +fn main() { } diff --git a/src/test/compile-fail/variance-contravariant-arg-trait-match.rs b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs new file mode 100644 index 0000000000000..caaad4014adfa --- /dev/null +++ b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs @@ -0,0 +1,31 @@ +// Copyright 2015 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. + +#![allow(dead_code)] + +trait Get { + fn get(&self, t: T); +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : Get<&'max i32> +{ + impls_get::() //~ ERROR mismatched types +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : Get<&'min i32> +{ + impls_get::() +} + +fn impls_get() where G : Get { } + +fn main() { } diff --git a/src/test/compile-fail/variance-contravariant-self-trait-match.rs b/src/test/compile-fail/variance-contravariant-self-trait-match.rs new file mode 100644 index 0000000000000..013511ed517a8 --- /dev/null +++ b/src/test/compile-fail/variance-contravariant-self-trait-match.rs @@ -0,0 +1,31 @@ +// Copyright 2015 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. + +#![allow(dead_code)] + +trait Get { + fn get(&self); +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : 'max, &'max G : Get +{ + impls_get::<&'min G>(); //~ ERROR mismatched types +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : 'max, &'min G : Get +{ + impls_get::<&'max G>(); +} + +fn impls_get() where G : Get { } + +fn main() { } diff --git a/src/test/compile-fail/variance-covariant-arg-object.rs b/src/test/compile-fail/variance-covariant-arg-object.rs new file mode 100644 index 0000000000000..828c987c08212 --- /dev/null +++ b/src/test/compile-fail/variance-covariant-arg-object.rs @@ -0,0 +1,31 @@ +// Copyright 2015 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. + +#![allow(dead_code)] + +trait Get : 'static { + fn get(&self) -> T; +} + +fn get_min_from_max<'min, 'max>(v: Box>) + -> Box> + where 'max : 'min +{ + v +} + +fn get_max_from_min<'min, 'max, G>(v: Box>) + -> Box> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +fn main() { } diff --git a/src/test/compile-fail/variance-covariant-arg-trait-match.rs b/src/test/compile-fail/variance-covariant-arg-trait-match.rs new file mode 100644 index 0000000000000..17761b9c0b19e --- /dev/null +++ b/src/test/compile-fail/variance-covariant-arg-trait-match.rs @@ -0,0 +1,31 @@ +// Copyright 2015 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. + +#![allow(dead_code)] + +trait Get { + fn get(&self) -> T; +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : Get<&'max i32> +{ + impls_get::() +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : Get<&'min i32> +{ + impls_get::() //~ ERROR mismatched types +} + +fn impls_get() where G : Get { } + +fn main() { } diff --git a/src/test/compile-fail/variance-covariant-self-trait-match.rs b/src/test/compile-fail/variance-covariant-self-trait-match.rs new file mode 100644 index 0000000000000..4e94a3eeb46e6 --- /dev/null +++ b/src/test/compile-fail/variance-covariant-self-trait-match.rs @@ -0,0 +1,31 @@ +// Copyright 2015 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. + +#![allow(dead_code)] + +trait Get { + fn get() -> Self; +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : 'max, &'max G : Get +{ + impls_get::<&'min G>(); +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : 'max, &'min G : Get +{ + impls_get::<&'max G>(); //~ ERROR mismatched types +} + +fn impls_get() where G : Get { } + +fn main() { } diff --git a/src/test/compile-fail/variance-invariant-arg-object.rs b/src/test/compile-fail/variance-invariant-arg-object.rs new file mode 100644 index 0000000000000..9edb510b826a1 --- /dev/null +++ b/src/test/compile-fail/variance-invariant-arg-object.rs @@ -0,0 +1,31 @@ +// Copyright 2015 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. + +#![allow(dead_code)] + +trait Get : 'static { + fn get(&self, t: T) -> T; +} + +fn get_min_from_max<'min, 'max>(v: Box>) + -> Box> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +fn get_max_from_min<'min, 'max, G>(v: Box>) + -> Box> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +fn main() { } diff --git a/src/test/compile-fail/variance-invariant-arg-trait-match.rs b/src/test/compile-fail/variance-invariant-arg-trait-match.rs new file mode 100644 index 0000000000000..45fed0b083dc1 --- /dev/null +++ b/src/test/compile-fail/variance-invariant-arg-trait-match.rs @@ -0,0 +1,31 @@ +// Copyright 2015 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. + +#![allow(dead_code)] + +trait Get { + fn get(&self, t: T) -> T; +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : Get<&'max i32> +{ + impls_get::() //~ ERROR mismatched types +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : Get<&'min i32> +{ + impls_get::() //~ ERROR mismatched types +} + +fn impls_get() where G : Get { } + +fn main() { } diff --git a/src/test/compile-fail/variance-invariant-self-trait-match.rs b/src/test/compile-fail/variance-invariant-self-trait-match.rs new file mode 100644 index 0000000000000..b46cd302ae5ea --- /dev/null +++ b/src/test/compile-fail/variance-invariant-self-trait-match.rs @@ -0,0 +1,31 @@ +// Copyright 2015 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. + +#![allow(dead_code)] + +trait Get { + fn get(&self) -> Self; +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, &'max G : Get +{ + impls_get::<&'min G>(); //~ ERROR mismatched types +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, &'min G : Get +{ + impls_get::<&'max G>(); //~ ERROR mismatched types +} + +fn impls_get() where G : Get { } + +fn main() { } diff --git a/src/test/compile-fail/variance-regions-unused-direct.rs b/src/test/compile-fail/variance-regions-unused-direct.rs new file mode 100644 index 0000000000000..396e77652067d --- /dev/null +++ b/src/test/compile-fail/variance-regions-unused-direct.rs @@ -0,0 +1,25 @@ +// Copyright 2012 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. + +// Test that disallow lifetime parameters that are unused. + +use std::marker; + +struct Bivariant<'a>; //~ ERROR parameter `'a` is never used + +struct Struct<'a, 'd> { //~ ERROR parameter `'d` is never used + field: &'a [i32] +} + +trait Trait<'a, 'd> { //~ ERROR parameter `'d` is never used + fn method(&'a self); +} + +fn main() {} diff --git a/src/test/compile-fail/variance-regions-unused-indirect.rs b/src/test/compile-fail/variance-regions-unused-indirect.rs new file mode 100644 index 0000000000000..2d234ed7b5781 --- /dev/null +++ b/src/test/compile-fail/variance-regions-unused-indirect.rs @@ -0,0 +1,21 @@ +// Copyright 2012 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. + +// Test that disallow lifetime parameters that are unused. + +enum Foo<'a> { //~ ERROR parameter `'a` is never used + Foo1(Bar<'a>) +} + +enum Bar<'a> { //~ ERROR parameter `'a` is never used + Bar1(Foo<'a>) +} + +fn main() {} diff --git a/src/test/compile-fail/variance-trait-bounds.rs b/src/test/compile-fail/variance-trait-bounds.rs new file mode 100644 index 0000000000000..661979479237e --- /dev/null +++ b/src/test/compile-fail/variance-trait-bounds.rs @@ -0,0 +1,64 @@ +// Copyright 2014 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. + +#![deny(bivariance)] +#![allow(dead_code)] + +// Check that bounds on type parameters (other than `Self`) do not +// influence variance. + +#[rustc_variance] +trait Getter { //~ ERROR types=[[+];[-];[]] + fn get(&self) -> T; +} + +#[rustc_variance] +trait Setter { //~ ERROR types=[[-];[-];[]] + fn get(&self, T); +} + +#[rustc_variance] +struct TestStruct> { //~ ERROR types=[[+, +];[];[]] + t: T, u: U +} + +#[rustc_variance] +enum TestEnum> {//~ ERROR types=[[*, +];[];[]] + //~^ ERROR parameter `U` is never used + Foo(T) +} + +#[rustc_variance] +trait TestTrait> { //~ ERROR types=[[-, +];[-];[]] + fn getter(&self, u: U) -> T; +} + +#[rustc_variance] +trait TestTrait2 : Getter { //~ ERROR types=[[+];[-];[]] +} + +#[rustc_variance] +trait TestTrait3 { //~ ERROR types=[[-];[-];[]] + fn getter>(&self); +} + +#[rustc_variance] +struct TestContraStruct> { //~ ERROR types=[[*, +];[];[]] + //~^ ERROR parameter `U` is never used + t: T +} + +#[rustc_variance] +struct TestBox+Setter> { //~ ERROR types=[[*, +];[];[]] + //~^ ERROR parameter `U` is never used + t: T +} + +pub fn main() { } diff --git a/src/test/compile-fail/variance-types-bounds.rs b/src/test/compile-fail/variance-types-bounds.rs new file mode 100644 index 0000000000000..c60649878feaf --- /dev/null +++ b/src/test/compile-fail/variance-types-bounds.rs @@ -0,0 +1,74 @@ +// Copyright 2012 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. + +// Test that we correctly infer variance for type parameters in +// various types and traits. + +#[rustc_variance] +struct TestImm { //~ ERROR types=[[+, +];[];[]] + x: A, + y: B, +} + +#[rustc_variance] +struct TestMut { //~ ERROR types=[[+, o];[];[]] + x: A, + y: &'static mut B, +} + +#[rustc_variance] +struct TestIndirect { //~ ERROR types=[[+, o];[];[]] + m: TestMut +} + +#[rustc_variance] +struct TestIndirect2 { //~ ERROR types=[[o, o];[];[]] + n: TestMut, + m: TestMut +} + +#[rustc_variance] +trait Getter { //~ ERROR types=[[+];[-];[]] + fn get(&self) -> A; +} + +#[rustc_variance] +trait Setter { //~ ERROR types=[[-];[o];[]] + fn set(&mut self, a: A); +} + +#[rustc_variance] +trait GetterSetter { //~ ERROR types=[[o];[o];[]] + fn get(&self) -> A; + fn set(&mut self, a: A); +} + +#[rustc_variance] +trait GetterInTypeBound { //~ ERROR types=[[-];[-];[]] + // Here, the use of `A` in the method bound *does* affect + // variance. Think of it as if the method requested a dictionary + // for `T:Getter`. Since this dictionary is an input, it is + // contravariant, and the Getter is covariant w/r/t A, yielding an + // overall contravariant result. + fn do_it>(&self); +} + +#[rustc_variance] +trait SetterInTypeBound { //~ ERROR types=[[+];[-];[]] + fn do_it>(&self); +} + +#[rustc_variance] +struct TestObject { //~ ERROR types=[[-, +];[];[]] + n: Box+Send>, + m: Box+Send>, +} + +fn main() {} diff --git a/src/test/compile-fail/variance-types.rs b/src/test/compile-fail/variance-types.rs new file mode 100644 index 0000000000000..6f6dd72769283 --- /dev/null +++ b/src/test/compile-fail/variance-types.rs @@ -0,0 +1,51 @@ +// Copyright 2014 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. + +#![deny(bivariance)] +#![allow(dead_code)] + +use std::cell::Cell; + +// Check that a type parameter which is only used in a trait bound is +// not considered bivariant. + +#[rustc_variance] +struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR types=[[o, o];[];[]], regions=[[-];[];[]] + t: &'a mut (A,B) +} + +#[rustc_variance] +struct InvariantCell { //~ ERROR types=[[o];[];[]] + t: Cell +} + +#[rustc_variance] +struct InvariantIndirect { //~ ERROR types=[[o];[];[]] + t: InvariantCell +} + +#[rustc_variance] +struct Covariant { //~ ERROR types=[[+];[];[]] + t: A, u: fn() -> A +} + +#[rustc_variance] +struct Contravariant { //~ ERROR types=[[-];[];[]] + t: fn(A) +} + +#[rustc_variance] +enum Enum { //~ ERROR types=[[+, -, o];[];[]] + Foo(Covariant), + Bar(Contravariant), + Zed(Covariant,Contravariant) +} + +pub fn main() { } diff --git a/src/test/compile-fail/variance-unused-region-param.rs b/src/test/compile-fail/variance-unused-region-param.rs new file mode 100644 index 0000000000000..5f504226370a4 --- /dev/null +++ b/src/test/compile-fail/variance-unused-region-param.rs @@ -0,0 +1,17 @@ +// Copyright 2012 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. + +// Test that we report an error for unused type parameters in types. + +struct SomeStruct<'a> { x: u32 } //~ ERROR parameter `'a` is never used +enum SomeEnum<'a> { Nothing } //~ ERROR parameter `'a` is never used +trait SomeTrait<'a> { fn foo(&self); } //~ ERROR parameter `'a` is never used + +fn main() {} diff --git a/src/test/compile-fail/variance-unused-type-param.rs b/src/test/compile-fail/variance-unused-type-param.rs new file mode 100644 index 0000000000000..2e867ec3c9384 --- /dev/null +++ b/src/test/compile-fail/variance-unused-type-param.rs @@ -0,0 +1,36 @@ +// Copyright 2012 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. + +#![allow(dead_code)] + +// Test that we report an error for unused type parameters in types and traits, +// and that we offer a helpful suggestion. + +struct SomeStruct { x: u32 } +//~^ ERROR parameter `A` is never used +//~| HELP PhantomData + +enum SomeEnum { Nothing } +//~^ ERROR parameter `A` is never used +//~| HELP PhantomData + +trait SomeTrait { fn foo(&self); } +//~^ ERROR parameter `A` is never used +//~| HELP PhantomFn + +// Here T might *appear* used, but in fact it isn't. +enum ListCell { +//~^ ERROR parameter `T` is never used +//~| HELP PhantomData + Cons(Box>), + Nil +} + +fn main() {} diff --git a/src/test/compile-fail/variance-use-contravariant-struct-1.rs b/src/test/compile-fail/variance-use-contravariant-struct-1.rs new file mode 100644 index 0000000000000..21a9e2477df7c --- /dev/null +++ b/src/test/compile-fail/variance-use-contravariant-struct-1.rs @@ -0,0 +1,24 @@ +// Copyright 2015 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. + +// Test various uses of structs with distint variances to make sure +// they permit lifetimes to be approximated as expected. + +struct SomeStruct(fn(T)); + +fn foo<'min,'max>(v: SomeStruct<&'max ()>) + -> SomeStruct<&'min ()> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +#[rustc_error] +fn main() { } diff --git a/src/test/compile-fail/variance-use-contravariant-struct-2.rs b/src/test/compile-fail/variance-use-contravariant-struct-2.rs new file mode 100644 index 0000000000000..dd80ac91683b4 --- /dev/null +++ b/src/test/compile-fail/variance-use-contravariant-struct-2.rs @@ -0,0 +1,26 @@ +// Copyright 2015 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. + +// Test various uses of structs with distint variances to make sure +// they permit lifetimes to be approximated as expected. + +#![allow(dead_code)] + +struct SomeStruct(fn(T)); + +fn bar<'min,'max>(v: SomeStruct<&'min ()>) + -> SomeStruct<&'max ()> + where 'max : 'min +{ + v +} + +#[rustc_error] +fn main() { } //~ ERROR compilation successful diff --git a/src/test/compile-fail/variance-use-covariant-struct-1.rs b/src/test/compile-fail/variance-use-covariant-struct-1.rs new file mode 100644 index 0000000000000..2631cfc05e81d --- /dev/null +++ b/src/test/compile-fail/variance-use-covariant-struct-1.rs @@ -0,0 +1,23 @@ +// Copyright 2015 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. + +// Test that a covariant struct does not permit the lifetime of a +// reference to be enlarged. + +struct SomeStruct(T); + +fn foo<'min,'max>(v: SomeStruct<&'min ()>) + -> SomeStruct<&'max ()> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +fn main() { } diff --git a/src/test/compile-fail/variance-use-covariant-struct-2.rs b/src/test/compile-fail/variance-use-covariant-struct-2.rs new file mode 100644 index 0000000000000..f85f7bb6a384f --- /dev/null +++ b/src/test/compile-fail/variance-use-covariant-struct-2.rs @@ -0,0 +1,25 @@ +// Copyright 2015 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. + +// Test that a covariant struct permits the lifetime of a reference to +// be shortened. + +#![allow(dead_code)] + +struct SomeStruct(T); + +fn foo<'min,'max>(v: SomeStruct<&'max ()>) + -> SomeStruct<&'min ()> + where 'max : 'min +{ + v +} + +#[rustc_error] fn main() { } //~ ERROR compilation successful diff --git a/src/test/compile-fail/variance-use-invariant-struct-1.rs b/src/test/compile-fail/variance-use-invariant-struct-1.rs new file mode 100644 index 0000000000000..b544ef00fc0a3 --- /dev/null +++ b/src/test/compile-fail/variance-use-invariant-struct-1.rs @@ -0,0 +1,31 @@ +// Copyright 2015 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. + +// Test various uses of structs with distint variances to make sure +// they permit lifetimes to be approximated as expected. + +struct SomeStruct(*mut T); + +fn foo<'min,'max>(v: SomeStruct<&'max ()>) + -> SomeStruct<&'min ()> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +fn bar<'min,'max>(v: SomeStruct<&'min ()>) + -> SomeStruct<&'max ()> + where 'max : 'min +{ + v //~ ERROR mismatched types +} + +#[rustc_error] +fn main() { } diff --git a/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs b/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs new file mode 100644 index 0000000000000..948d68e0ccd7d --- /dev/null +++ b/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs @@ -0,0 +1,34 @@ +// Copyright 2015 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. + +// Elaborated version of the opening example from RFC 738. This failed +// to compile before variance because invariance of `Option` prevented +// us from approximating the lifetimes of `field1` and `field2` to a +// common intersection. + +#![allow(dead_code)] + +struct List<'l> { + field1: &'l i32, + field2: Option<&'l i32>, +} + +fn foo(field1: &i32, field2: Option<&i32>) -> i32 { + let list = List { field1: field1, field2: field2 }; + *list.field1 + list.field2.cloned().unwrap_or(0) +} + +fn main() { + let x = 22; + let y = Some(3); + let z = None; + assert_eq!(foo(&x, y.as_ref()), 25); + assert_eq!(foo(&x, z.as_ref()), 22); +} diff --git a/src/test/run-pass/variance-trait-matching.rs b/src/test/run-pass/variance-trait-matching.rs new file mode 100644 index 0000000000000..10441bee3cb9f --- /dev/null +++ b/src/test/run-pass/variance-trait-matching.rs @@ -0,0 +1,49 @@ +// Copyright 2015 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. + +#![allow(dead_code)] + +// Get is covariant in T +trait Get { + fn get(&self) -> T; +} + +struct Cloner { + t: T +} + +impl Get for Cloner { + fn get(&self) -> T { + self.t.clone() + } +} + +fn get<'a, G>(get: &G) -> i32 + where G : Get<&'a i32> +{ + // This call only type checks if we can use `G : Get<&'a i32>` as + // evidence that `G : Get<&'b i32>` where `'a : 'b`. + pick(get, &22) +} + +fn pick<'b, G>(get: &'b G, if_odd: &'b i32) -> i32 + where G : Get<&'b i32> +{ + let v = *get.get(); + if v % 2 != 0 { v } else { *if_odd } +} + +fn main() { + let x = Cloner { t: &23 }; + let y = get(&x); + assert_eq!(y, 23); +} + + diff --git a/src/test/run-pass/variance-vec-covariant.rs b/src/test/run-pass/variance-vec-covariant.rs new file mode 100644 index 0000000000000..caec6df5a4d81 --- /dev/null +++ b/src/test/run-pass/variance-vec-covariant.rs @@ -0,0 +1,28 @@ +// Copyright 2015 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. + +// Test that vec is now covariant in its argument type. + +#![allow(dead_code)] + +fn foo<'a,'b>(v1: Vec<&'a i32>, v2: Vec<&'b i32>) -> i32 { + bar(v1, v2).cloned().unwrap_or(0) // only type checks if we can intersect 'a and 'b +} + +fn bar<'c>(v1: Vec<&'c i32>, v2: Vec<&'c i32>) -> Option<&'c i32> { + v1.get(0).cloned().or_else(|| v2.get(0).cloned()) +} + +fn main() { + let x = 22; + let y = 44; + assert_eq!(foo(vec![&x], vec![&y]), 22); + assert_eq!(foo(vec![&y], vec![&x]), 44); +} From 91eedfe18b9be80b69ef2f19f4b618b2968ba181 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 12:48:01 -0500 Subject: [PATCH 19/76] Report errors for type parameters that are not constrained, either by variance or an associated type. --- src/librustc/middle/ty.rs | 7 + src/librustc_typeck/check/wf.rs | 150 ++++++++++++++++-- src/librustc_typeck/collect.rs | 56 +------ .../constrained_type_params.rs | 20 +-- src/librustc_typeck/lib.rs | 1 + src/test/compile-fail/issue-17904-2.rs | 16 ++ 6 files changed, 180 insertions(+), 70 deletions(-) create mode 100644 src/test/compile-fail/issue-17904-2.rs diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8618bde95fe6f..503def14fcdeb 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2955,6 +2955,13 @@ impl<'tcx> TyS<'tcx> { assert_eq!(r, Some(self)); walker } + + pub fn as_opt_param_ty(&self) -> Option { + match self.sty { + ty::ty_param(ref d) => Some(d.clone()), + _ => None, + } + } } pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F) diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 94670305be755..da5dbb2260803 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -10,21 +10,22 @@ use astconv::AstConv; use check::{FnCtxt, Inherited, blank_fn_ctxt, vtable, regionck}; +use constrained_type_params::identify_constrained_type_params; use CrateCtxt; use middle::region; -use middle::subst; +use middle::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace}; use middle::traits; use middle::ty::{self, Ty}; use middle::ty::liberate_late_bound_regions; use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty}; -use util::ppaux::Repr; +use util::ppaux::{Repr, UserString}; use std::collections::HashSet; use syntax::ast; use syntax::ast_util::{local_def}; use syntax::attr; use syntax::codemap::Span; -use syntax::parse::token; +use syntax::parse::token::{self, special_idents}; use syntax::visit; use syntax::visit::Visitor; @@ -38,6 +39,10 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { CheckTypeWellFormedVisitor { ccx: ccx, cache: HashSet::new() } } + fn tcx(&self) -> &ty::ctxt<'tcx> { + self.ccx.tcx + } + /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are /// well-formed, meaning that they do not require any constraints not declared in the struct /// definition itself. For example, this definition would be illegal: @@ -96,23 +101,29 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { ast::ItemConst(..) => { self.check_item_type(item); } - ast::ItemStruct(ref struct_def, _) => { + ast::ItemStruct(ref struct_def, ref ast_generics) => { self.check_type_defn(item, |fcx| { vec![struct_variant(fcx, &**struct_def)] }); + + self.check_variances_for_type_defn(item, ast_generics); } - ast::ItemEnum(ref enum_def, _) => { + ast::ItemEnum(ref enum_def, ref ast_generics) => { self.check_type_defn(item, |fcx| { enum_variants(fcx, enum_def) }); + + self.check_variances_for_type_defn(item, ast_generics); } - ast::ItemTrait(..) => { + ast::ItemTrait(_, ref ast_generics, _, _) => { let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(item.id)); reject_non_type_param_bounds( ccx.tcx, item.span, &trait_predicates); + self.check_variances(item, ast_generics, &trait_predicates, + self.tcx().lang_items.phantom_fn()); } _ => {} } @@ -280,6 +291,123 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { } }); } + + fn check_variances_for_type_defn(&self, + item: &ast::Item, + ast_generics: &ast::Generics) + { + let item_def_id = local_def(item.id); + let predicates = ty::lookup_predicates(self.tcx(), item_def_id); + self.check_variances(item, + ast_generics, + &predicates, + self.tcx().lang_items.phantom_data()); + } + + fn check_variances(&self, + item: &ast::Item, + ast_generics: &ast::Generics, + ty_predicates: &ty::GenericPredicates<'tcx>, + suggested_marker_id: Option) + { + let variance_lang_items = &[ + self.tcx().lang_items.phantom_fn(), + self.tcx().lang_items.phantom_data(), + ]; + + let item_def_id = local_def(item.id); + let is_lang_item = variance_lang_items.iter().any(|n| *n == Some(item_def_id)); + if is_lang_item { + return; + } + + let variances = ty::item_variances(self.tcx(), item_def_id); + + let mut constrained_parameters: HashSet<_> = + variances.types + .iter_enumerated() + .filter(|&(_, _, &variance)| variance != ty::Bivariant) + .map(|(space, index, _)| self.param_ty(ast_generics, space, index)) + .collect(); + + identify_constrained_type_params(self.tcx(), + ty_predicates.predicates.as_slice(), + None, + &mut constrained_parameters); + + for (space, index, _) in variances.types.iter_enumerated() { + let param_ty = self.param_ty(ast_generics, space, index); + if constrained_parameters.contains(¶m_ty) { + continue; + } + let span = self.ty_param_span(ast_generics, item, space, index); + self.report_bivariance(span, param_ty.name, suggested_marker_id); + } + + for (space, index, &variance) in variances.regions.iter_enumerated() { + if variance != ty::Bivariant { + continue; + } + + assert_eq!(space, TypeSpace); + let span = ast_generics.lifetimes[index].lifetime.span; + let name = ast_generics.lifetimes[index].lifetime.name; + self.report_bivariance(span, name, suggested_marker_id); + } + } + + fn param_ty(&self, + ast_generics: &ast::Generics, + space: ParamSpace, + index: usize) + -> ty::ParamTy + { + let name = match space { + TypeSpace => ast_generics.ty_params[index].ident.name, + SelfSpace => special_idents::type_self.name, + FnSpace => self.tcx().sess.bug("Fn space occupied?"), + }; + + ty::ParamTy { space: space, idx: index as u32, name: name } + } + + fn ty_param_span(&self, + ast_generics: &ast::Generics, + item: &ast::Item, + space: ParamSpace, + index: usize) + -> Span + { + match space { + TypeSpace => ast_generics.ty_params[index].span, + SelfSpace => item.span, + FnSpace => self.tcx().sess.span_bug(item.span, "Fn space occupied?"), + } + } + + fn report_bivariance(&self, + span: Span, + param_name: ast::Name, + suggested_marker_id: Option) + { + self.tcx().sess.span_err( + span, + &format!("parameter `{}` is never used", + param_name.user_string(self.tcx()))[]); + + match suggested_marker_id { + Some(def_id) => { + self.tcx().sess.span_help( + span, + format!("consider removing `{}` or using a marker such as `{}`", + param_name.user_string(self.tcx()), + ty::item_path_str(self.tcx(), def_id)).as_slice()); + } + None => { + // no lang items, no help! + } + } + } } // Reject any predicates that do not involve a type parameter. @@ -347,9 +475,9 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { match fk { visit::FkFnBlock | visit::FkItemFn(..) => {} visit::FkMethod(..) => { - match ty::impl_or_trait_item(self.ccx.tcx, local_def(id)) { + match ty::impl_or_trait_item(self.tcx(), local_def(id)) { ty::ImplOrTraitItem::MethodTraitItem(ty_method) => { - reject_shadowing_type_parameters(self.ccx.tcx, span, &ty_method.generics) + reject_shadowing_type_parameters(self.tcx(), span, &ty_method.generics) } _ => {} } @@ -363,14 +491,14 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { &ast::TraitItem::ProvidedMethod(_) | &ast::TraitItem::TypeTraitItem(_) => {}, &ast::TraitItem::RequiredMethod(ref method) => { - match ty::impl_or_trait_item(self.ccx.tcx, local_def(method.id)) { + match ty::impl_or_trait_item(self.tcx(), local_def(method.id)) { ty::ImplOrTraitItem::MethodTraitItem(ty_method) => { reject_non_type_param_bounds( - self.ccx.tcx, + self.tcx(), method.span, &ty_method.predicates); reject_shadowing_type_parameters( - self.ccx.tcx, + self.tcx(), method.span, &ty_method.generics); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 44e850a073800..32679c8967e7b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -87,6 +87,7 @@ There are some shortcomings in this design: use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region}; use middle::def; +use constrained_type_params::identify_constrained_type_params; use middle::lang_items::SizedTraitLangItem; use middle::region; use middle::resolve_lifetime; @@ -1960,51 +1961,15 @@ fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>, let mut input_parameters: HashSet<_> = impl_trait_ref.iter() .flat_map(|t| t.input_types().iter()) // Types in trait ref, if any - .chain(Some(impl_scheme.ty).iter()) // Self type, always + .chain(Some(impl_scheme.ty).iter()) // Self type, always .flat_map(|t| t.walk()) - .filter_map(to_opt_param_ty) + .filter_map(|t| t.as_opt_param_ty()) .collect(); - loop { - let num_inputs = input_parameters.len(); - - let projection_predicates = - impl_predicates.predicates - .iter() - .filter_map(|predicate| { - match *predicate { - // Ignore higher-ranked binders. For the purposes - // of this check, they don't matter because they - // only affect named regions, and we're just - // concerned about type parameters here. - ty::Predicate::Projection(ref data) => Some(data.0.clone()), - _ => None, - } - }); - - for projection in projection_predicates { - // Special case: watch out for some kind of sneaky attempt - // to project out an associated type defined by this very trait. - if Some(projection.projection_ty.trait_ref.clone()) == impl_trait_ref { - continue; - } - - let relies_only_on_inputs = - projection.projection_ty.trait_ref.input_types().iter() - .flat_map(|t| t.walk()) - .filter_map(to_opt_param_ty) - .all(|t| input_parameters.contains(&t)); - - if relies_only_on_inputs { - input_parameters.extend( - projection.ty.walk().filter_map(to_opt_param_ty)); - } - } - - if input_parameters.len() == num_inputs { - break; - } - } + identify_constrained_type_params(tcx, + impl_predicates.predicates.as_slice(), + impl_trait_ref, + &mut input_parameters); for (index, ty_param) in ast_generics.ty_params.iter().enumerate() { let param_ty = ty::ParamTy { space: TypeSpace, @@ -2025,11 +1990,4 @@ fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>, } } } - - fn to_opt_param_ty<'tcx>(ty: Ty<'tcx>) -> Option { - match ty.sty { - ty::ty_param(ref d) => Some(d.clone()), - _ => None, - } - } } diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs index f40add8e2c0ab..83d7e98500007 100644 --- a/src/librustc_typeck/constrained_type_params.rs +++ b/src/librustc_typeck/constrained_type_params.rs @@ -23,16 +23,16 @@ pub fn identify_constrained_type_params<'tcx>(_tcx: &ty::ctxt<'tcx>, let projection_predicates = predicates.iter() - .filter_map(|predicate| { - match *predicate { - // Ignore higher-ranked binders. For the purposes - // of this check, they don't matter because they - // only affect named regions, and we're just - // concerned about type parameters here. - ty::Predicate::Projection(ref data) => Some(data.0.clone()), - _ => None, - } - }); + .filter_map(|predicate| { + match *predicate { + // Ignore higher-ranked binders. For the purposes + // of this check, they don't matter because they + // only affect named regions, and we're just + // concerned about type parameters here. + ty::Predicate::Projection(ref data) => Some(data.0.clone()), + _ => None, + } + }); for projection in projection_predicates { // Special case: watch out for some kind of sneaky attempt diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 7498dc8179d75..b5dca0bd4f6f4 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -123,6 +123,7 @@ mod check; mod rscope; mod astconv; mod collect; +mod constrained_type_params; mod coherence; mod variance; diff --git a/src/test/compile-fail/issue-17904-2.rs b/src/test/compile-fail/issue-17904-2.rs new file mode 100644 index 0000000000000..a33ec23a16a51 --- /dev/null +++ b/src/test/compile-fail/issue-17904-2.rs @@ -0,0 +1,16 @@ +// Copyright 2014 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. + +// Test that we can parse a unit struct with a where clause, even if +// it leads to a error later on since `T` is unused. + +struct Foo where T: Copy; //~ ERROR parameter `T` is never used + +fn main() {} From 8c841f2a310ccad73059ed9f74232f14e8f680bb Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 12:42:02 -0500 Subject: [PATCH 20/76] Extend coherence check to understand subtyping. --- src/librustc/middle/traits/coherence.rs | 101 +++++++++++++------ src/librustc/middle/traits/mod.rs | 11 +- src/test/compile-fail/coherence-subtyping.rs | 50 +++++++++ 3 files changed, 123 insertions(+), 39 deletions(-) create mode 100644 src/test/compile-fail/coherence-subtyping.rs diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 3a7522cafee90..e199a60c370e3 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -10,24 +10,27 @@ //! See `doc.rs` for high-level documentation +use super::Normalized; use super::SelectionContext; -use super::{Obligation, ObligationCause}; +use super::{ObligationCause}; +use super::PredicateObligation; use super::project; use super::util; use middle::subst::{Subst, TypeSpace}; -use middle::ty::{self, Ty}; -use middle::infer::InferCtxt; +use middle::ty::{self, ToPolyTraitRef, Ty}; +use middle::infer::{self, InferCtxt}; use std::collections::HashSet; use std::rc::Rc; use syntax::ast; use syntax::codemap::DUMMY_SP; use util::ppaux::Repr; -pub fn impl_can_satisfy(infcx: &InferCtxt, - impl1_def_id: ast::DefId, - impl2_def_id: ast::DefId) - -> bool +/// True if there exist types that satisfy both of the two given impls. +pub fn overlapping_impls(infcx: &InferCtxt, + impl1_def_id: ast::DefId, + impl2_def_id: ast::DefId) + -> bool { debug!("impl_can_satisfy(\ impl1_def_id={}, \ @@ -35,28 +38,68 @@ pub fn impl_can_satisfy(infcx: &InferCtxt, impl1_def_id.repr(infcx.tcx), impl2_def_id.repr(infcx.tcx)); - let param_env = ty::empty_parameter_environment(infcx.tcx); - let mut selcx = SelectionContext::intercrate(infcx, ¶m_env); - let cause = ObligationCause::dummy(); - - // `impl1` provides an implementation of `Foo for Z`. - let impl1_substs = - util::fresh_substs_for_impl(infcx, DUMMY_SP, impl1_def_id); - let impl1_trait_ref = - (*ty::impl_trait_ref(infcx.tcx, impl1_def_id).unwrap()).subst(infcx.tcx, &impl1_substs); - let impl1_trait_ref = - project::normalize(&mut selcx, cause.clone(), &impl1_trait_ref); - - // Determine whether `impl2` can provide an implementation for those - // same types. - let obligation = Obligation::new(cause, - ty::Binder(ty::TraitPredicate { - trait_ref: Rc::new(impl1_trait_ref.value), - })); - debug!("impl_can_satisfy(obligation={})", obligation.repr(infcx.tcx)); - selcx.evaluate_impl(impl2_def_id, &obligation) && - impl1_trait_ref.obligations.iter().all( - |o| selcx.evaluate_obligation(o)) + let param_env = &ty::empty_parameter_environment(infcx.tcx); + let selcx = &mut SelectionContext::intercrate(infcx, param_env); + infcx.probe(|_| { + overlap(selcx, impl1_def_id, impl2_def_id) || overlap(selcx, impl2_def_id, impl1_def_id) + }) +} + +/// Can the types from impl `a` be used to satisfy impl `b`? +/// (Including all conditions) +fn overlap(selcx: &mut SelectionContext, + a_def_id: ast::DefId, + b_def_id: ast::DefId) + -> bool +{ + let (a_trait_ref, a_obligations) = impl_trait_ref_and_oblig(selcx, a_def_id); + let (b_trait_ref, b_obligations) = impl_trait_ref_and_oblig(selcx, b_def_id); + + // Does `a <: b` hold? If not, no overlap. + if let Err(_) = infer::mk_sub_poly_trait_refs(selcx.infcx(), + true, + infer::Misc(DUMMY_SP), + a_trait_ref.to_poly_trait_ref(), + b_trait_ref.to_poly_trait_ref()) { + return false; + } + + // Are any of the obligations unsatisfiable? If so, no overlap. + a_obligations.iter() + .chain(b_obligations.iter()) + .all(|o| selcx.evaluate_obligation(o)) +} + +/// Instantiate fresh variables for all bound parameters of the impl +/// and return the impl trait ref with those variables substituted. +fn impl_trait_ref_and_oblig<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, + impl_def_id: ast::DefId) + -> (Rc>, + Vec>) +{ + let impl_substs = + &util::fresh_substs_for_impl(selcx.infcx(), DUMMY_SP, impl_def_id); + let impl_trait_ref = + ty::impl_trait_ref(selcx.tcx(), impl_def_id).unwrap(); + let impl_trait_ref = + impl_trait_ref.subst(selcx.tcx(), impl_substs); + let Normalized { value: impl_trait_ref, obligations: normalization_obligations1 } = + project::normalize(selcx, ObligationCause::dummy(), &impl_trait_ref); + + let predicates = ty::lookup_predicates(selcx.tcx(), impl_def_id); + let predicates = predicates.instantiate(selcx.tcx(), impl_substs); + let Normalized { value: predicates, obligations: normalization_obligations2 } = + project::normalize(selcx, ObligationCause::dummy(), &predicates); + let impl_obligations = + util::predicates_for_generics(selcx.tcx(), ObligationCause::dummy(), 0, &predicates); + + let impl_obligations: Vec<_> = + impl_obligations.into_iter() + .chain(normalization_obligations1.into_iter()) + .chain(normalization_obligations2.into_iter()) + .collect(); + + (impl_trait_ref, impl_obligations) } pub enum OrphanCheckErr<'tcx> { diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 83090dd72aa94..2e4bcdf0478ce 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -28,6 +28,7 @@ use util::ppaux::{Repr, UserString}; pub use self::error_reporting::report_fulfillment_errors; pub use self::error_reporting::suggest_new_overflow_limit; pub use self::coherence::orphan_check; +pub use self::coherence::overlapping_impls; pub use self::coherence::OrphanCheckErr; pub use self::fulfill::{FulfillmentContext, RegionObligation}; pub use self::project::MismatchedProjectionTypes; @@ -270,16 +271,6 @@ pub struct VtableObjectData<'tcx> { pub object_ty: Ty<'tcx>, } -/// True if there exist types that satisfy both of the two given impls. -pub fn overlapping_impls(infcx: &InferCtxt, - impl1_def_id: ast::DefId, - impl2_def_id: ast::DefId) - -> bool -{ - coherence::impl_can_satisfy(infcx, impl1_def_id, impl2_def_id) && - coherence::impl_can_satisfy(infcx, impl2_def_id, impl1_def_id) -} - /// Creates predicate obligations from the generic bounds. pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>, cause: ObligationCause<'tcx>, diff --git a/src/test/compile-fail/coherence-subtyping.rs b/src/test/compile-fail/coherence-subtyping.rs new file mode 100644 index 0000000000000..897cb083f849d --- /dev/null +++ b/src/test/compile-fail/coherence-subtyping.rs @@ -0,0 +1,50 @@ +// Copyright 2015 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. + +// Test that two distinct impls which match subtypes of one another +// yield coherence errors (or not) depending on the variance. + +trait Contravariant { + fn foo(&self) { } +} + +impl Contravariant for for<'a,'b> fn(&'a u8, &'b u8) { + //~^ ERROR E0119 +} + +impl Contravariant for for<'a> fn(&'a u8, &'a u8) { +} + +/////////////////////////////////////////////////////////////////////////// + +trait Covariant { + fn foo(&self) { } +} + +impl Covariant for for<'a,'b> fn(&'a u8, &'b u8) { + //~^ ERROR E0119 +} + +impl Covariant for for<'a> fn(&'a u8, &'a u8) { +} + +/////////////////////////////////////////////////////////////////////////// + +trait Invariant { + fn foo(&self) -> Self { } +} + +impl Invariant for for<'a,'b> fn(&'a u8, &'b u8) { +} + +impl Invariant for for<'a> fn(&'a u8, &'a u8) { +} + +fn main() { } From 801bc48939e6df1678ad2934ce35d981a068f253 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 10:33:21 -0500 Subject: [PATCH 21/76] Rewrite `Unique` so that it is covariant in T, implies `NonZero` and ownership, and also follows the API of `NonZero` a bit more closely. More to do here I think (including perhaps a new name). --- src/libcore/nonzero.rs | 9 ++++---- src/libcore/ptr.rs | 52 ++++++++++++++++++++++++++---------------- src/libcoretest/ptr.rs | 4 ++-- 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 5644f76306929..230587b726fd1 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -10,15 +10,14 @@ //! Exposes the NonZero lang item which provides optimization hints. +use marker::{Sized, MarkerTrait}; use ops::Deref; -use ptr::Unique; /// Unsafe trait to indicate what types are usable with the NonZero struct -pub unsafe trait Zeroable {} +pub unsafe trait Zeroable : MarkerTrait {} -unsafe impl Zeroable for *const T {} -unsafe impl Zeroable for *mut T {} -unsafe impl Zeroable for Unique { } +unsafe impl Zeroable for *const T {} +unsafe impl Zeroable for *mut T {} unsafe impl Zeroable for isize {} unsafe impl Zeroable for usize {} unsafe impl Zeroable for i8 {} diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 072c60c7036cf..8fb8d30a3b8d4 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -91,8 +91,10 @@ use mem; use clone::Clone; use intrinsics; +use ops::Deref; use option::Option::{self, Some, None}; -use marker::{self, Send, Sized, Sync}; +use marker::{PhantomData, Send, Sized, Sync}; +use nonzero::NonZero; use cmp::{PartialEq, Eq, Ord, PartialOrd}; use cmp::Ordering::{self, Less, Equal, Greater}; @@ -517,15 +519,16 @@ impl PartialOrd for *mut T { /// A wrapper around a raw `*mut T` that indicates that the possessor /// of this wrapper owns the referent. This in turn implies that the -/// `Unique` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a -/// raw `*mut T` (which conveys no particular ownership semantics). -/// Useful for building abstractions like `Vec` or `Box`, which +/// `Unique` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a raw +/// `*mut T` (which conveys no particular ownership semantics). It +/// also implies that the referent of the pointer should not be +/// modified without a unique path to the `Unique` reference. Useful +/// for building abstractions like `Vec` or `Box`, which /// internally use raw pointers to manage the memory that they own. #[unstable(feature = "core", reason = "recently added to this module")] -pub struct Unique { - /// The wrapped `*mut T`. - pub ptr: *mut T, - _own: marker::PhantomData, +pub struct Unique { + pointer: NonZero<*const T>, + _marker: PhantomData, } /// `Unique` pointers are `Send` if `T` is `Send` because the data they @@ -542,25 +545,34 @@ unsafe impl Send for Unique { } #[unstable(feature = "core", reason = "recently added to this module")] unsafe impl Sync for Unique { } -impl Unique { - /// Returns a null Unique. +impl Unique { + /// Create a new `Unique`. #[unstable(feature = "core", reason = "recently added to this module")] - pub fn null() -> Unique { - Unique(null_mut()) + pub unsafe fn new(ptr: *mut T) -> Unique { + Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData } } - /// Return an (unsafe) pointer into the memory owned by `self`. + /// Dereference the content. #[unstable(feature = "core", reason = "recently added to this module")] - pub unsafe fn offset(self, offset: isize) -> *mut T { - self.ptr.offset(offset) + pub unsafe fn get(&self) -> &T { + &**self.pointer + } + + /// Mutably dereference the content. + #[unstable(feature = "core", + reason = "recently added to this module")] + pub unsafe fn get_mut(&mut self) -> &mut T { + &mut ***self } } -/// Creates a `Unique` wrapped around `ptr`, taking ownership of the -/// data referenced by `ptr`. -#[allow(non_snake_case)] -pub fn Unique(ptr: *mut T) -> Unique { - Unique { ptr: ptr, _own: marker::PhantomData } +impl Deref for Unique { + type Target = *mut T; + + #[inline] + fn deref<'a>(&'a self) -> &'a *mut T { + unsafe { mem::transmute(&*self.pointer) } + } } diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs index 9c2e242c10509..57456bfb1a79b 100644 --- a/src/libcoretest/ptr.rs +++ b/src/libcoretest/ptr.rs @@ -171,8 +171,8 @@ fn test_set_memory() { #[test] fn test_unsized_unique() { let xs: &mut [_] = &mut [1, 2, 3]; - let ptr = Unique(xs as *mut [_]); - let ys = unsafe { &mut *ptr.ptr }; + let ptr = unsafe { Unique::new(xs as *mut [_]) }; + let ys = unsafe { &mut **ptr }; let zs: &mut [_] = &mut [1, 2, 3]; assert!(ys == zs); } From f2529ac10d7ba68a03ce94873076afa9eb52e365 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 12:48:54 -0500 Subject: [PATCH 22/76] Constrain operands to outlive the operation. Fixes #21422. --- src/librustc/middle/infer/error_reporting.rs | 16 +++++++++++++ src/librustc/middle/infer/mod.rs | 5 ++++ src/librustc_typeck/check/regionck.rs | 14 +++++++++++ src/test/run-pass/regions-issue-21422.rs | 25 ++++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 src/test/run-pass/regions-issue-21422.rs diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 72b33613c66aa..5f9f2ad33aa5b 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -675,6 +675,17 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { sup, ""); } + infer::Operand(span) => { + self.tcx.sess.span_err( + span, + "lifetime of operand does not outlive \ + the operation"); + note_and_explain_region( + self.tcx, + "the operand is only valid for ", + sup, + ""); + } infer::AddrOf(span) => { self.tcx.sess.span_err( span, @@ -1593,6 +1604,11 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { span, "...so that return value is valid for the call"); } + infer::Operand(span) => { + self.tcx.sess.span_err( + span, + "...so that operand is valid for operation"); + } infer::AddrOf(span) => { self.tcx.sess.span_note( span, diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 3cffe4c0fda40..b0576ff55ff73 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -210,6 +210,9 @@ pub enum SubregionOrigin<'tcx> { // Region in return type of invoked fn must enclose call CallReturn(Span), + // Operands must be in scope + Operand(Span), + // Region resulting from a `&` expr must enclose the `&` expr AddrOf(Span), @@ -1195,6 +1198,7 @@ impl<'tcx> SubregionOrigin<'tcx> { CallRcvr(a) => a, CallArg(a) => a, CallReturn(a) => a, + Operand(a) => a, AddrOf(a) => a, AutoBorrow(a) => a, SafeDestructor(a) => a, @@ -1258,6 +1262,7 @@ impl<'tcx> Repr<'tcx> for SubregionOrigin<'tcx> { CallRcvr(a) => format!("CallRcvr({})", a.repr(tcx)), CallArg(a) => format!("CallArg({})", a.repr(tcx)), CallReturn(a) => format!("CallReturn({})", a.repr(tcx)), + Operand(a) => format!("Operand({})", a.repr(tcx)), AddrOf(a) => format!("AddrOf({})", a.repr(tcx)), AutoBorrow(a) => format!("AutoBorrow({})", a.repr(tcx)), SafeDestructor(a) => format!("SafeDestructor({})", a.repr(tcx)), diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 17c259e674e9f..e50c3b0306ee3 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -610,6 +610,20 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { visit::walk_expr(rcx, expr); } + ast::ExprBinary(_, ref lhs, ref rhs) => { + // If you do `x OP y`, then the types of `x` and `y` must + // outlive the operation you are performing. + let lhs_ty = rcx.resolve_expr_type_adjusted(&**lhs); + let rhs_ty = rcx.resolve_expr_type_adjusted(&**rhs); + for &ty in [lhs_ty, rhs_ty].iter() { + type_must_outlive(rcx, + infer::Operand(expr.span), + ty, + ty::ReScope(CodeExtent::from_node_id(expr.id))); + } + visit::walk_expr(rcx, expr); + } + ast::ExprUnary(op, ref lhs) if has_method_map => { let implicitly_ref_args = !ast_util::is_by_value_unop(op); diff --git a/src/test/run-pass/regions-issue-21422.rs b/src/test/run-pass/regions-issue-21422.rs new file mode 100644 index 0000000000000..c59bf15afc3b0 --- /dev/null +++ b/src/test/run-pass/regions-issue-21422.rs @@ -0,0 +1,25 @@ +// Copyright 2015 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. + +// Regression test for issue #21422, which was related to failing to +// add inference constraints that the operands of a binary operator +// should outlive the binary operation itself. + +pub struct P<'a> { + _ptr: *const &'a u8, +} + +impl <'a> PartialEq for P<'a> { + fn eq(&self, other: &P<'a>) -> bool { + (self as *const _) == (other as *const _) + } +} + +fn main() {} From c5579ca340b346f1b685887f7784c2e7f2090dcb Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 10:30:39 -0500 Subject: [PATCH 23/76] Fallout: Port Vec to use `Unique` --- src/libcollections/vec.rs | 38 +++++++++++++++++------------------ src/libcollections/vec_map.rs | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index bde733644b5b5..1a03f5b31c0bf 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -57,13 +57,13 @@ use core::default::Default; use core::fmt; use core::hash::{self, Hash}; use core::iter::{repeat, FromIterator, IntoIterator}; -use core::marker::{self, ContravariantLifetime, InvariantType}; +use core::marker::PhantomData; use core::mem; -use core::nonzero::NonZero; use core::num::{Int, UnsignedInt}; use core::ops::{Index, IndexMut, Deref, Add}; use core::ops; use core::ptr; +use core::ptr::Unique; use core::raw::Slice as RawSlice; use core::slice; use core::usize; @@ -137,10 +137,9 @@ use core::usize; #[unsafe_no_drop_flag] #[stable(feature = "rust1", since = "1.0.0")] pub struct Vec { - ptr: NonZero<*mut T>, + ptr: Unique, len: usize, cap: usize, - _own: marker::PhantomData, } unsafe impl Send for Vec { } @@ -249,10 +248,9 @@ impl Vec { pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Vec { Vec { - ptr: NonZero::new(ptr), + ptr: Unique::new(ptr), len: length, cap: capacity, - _own: marker::PhantomData, } } @@ -373,7 +371,7 @@ impl Vec { self.len * mem::size_of::(), mem::min_align_of::()) as *mut T; if ptr.is_null() { ::alloc::oom() } - self.ptr = NonZero::new(ptr); + self.ptr = Unique::new(ptr); } self.cap = self.len; } @@ -655,7 +653,7 @@ impl Vec { unsafe { let ptr = alloc_or_realloc(*self.ptr, old_size, size); if ptr.is_null() { ::alloc::oom() } - self.ptr = NonZero::new(ptr); + self.ptr = Unique::new(ptr); } self.cap = max(self.cap, 2) * 2; } @@ -756,7 +754,7 @@ impl Vec { Drain { ptr: begin, end: end, - marker: ContravariantLifetime, + marker: PhantomData, } } } @@ -871,6 +869,8 @@ impl Vec { end_t: unsafe { start.offset(offset) }, start_u: start as *mut U, end_u: start as *mut U, + + _marker: PhantomData, }; // start_t // start_u @@ -967,8 +967,7 @@ impl Vec { let mut pv = PartialVecZeroSized:: { num_t: vec.len(), num_u: 0, - marker_t: InvariantType, - marker_u: InvariantType, + marker: PhantomData, }; unsafe { mem::forget(vec); } @@ -1226,7 +1225,7 @@ impl Vec { unsafe { let ptr = alloc_or_realloc(*self.ptr, self.cap * mem::size_of::(), size); if ptr.is_null() { ::alloc::oom() } - self.ptr = NonZero::new(ptr); + self.ptr = Unique::new(ptr); } self.cap = capacity; } @@ -1779,10 +1778,10 @@ impl Drop for IntoIter { #[unsafe_no_drop_flag] #[unstable(feature = "collections", reason = "recently added as part of collections reform 2")] -pub struct Drain<'a, T> { +pub struct Drain<'a, T:'a> { ptr: *const T, end: *const T, - marker: ContravariantLifetime<'a>, + marker: PhantomData<&'a T>, } #[stable(feature = "rust1", since = "1.0.0")] @@ -1867,9 +1866,9 @@ impl<'a, T> Drop for Drain<'a, T> { /// Wrapper type providing a `&Vec` reference via `Deref`. #[unstable(feature = "collections")] -pub struct DerefVec<'a, T> { +pub struct DerefVec<'a, T:'a> { x: Vec, - l: ContravariantLifetime<'a> + l: PhantomData<&'a T>, } #[unstable(feature = "collections")] @@ -1897,7 +1896,7 @@ pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> { unsafe { DerefVec { x: Vec::from_raw_parts(x.as_ptr() as *mut T, x.len(), x.len()), - l: ContravariantLifetime::<'a> + l: PhantomData, } } } @@ -1921,6 +1920,8 @@ struct PartialVecNonZeroSized { end_u: *mut U, start_t: *mut T, end_t: *mut T, + + _marker: PhantomData, } /// An owned, partially type-converted vector of zero-sized elements. @@ -1930,8 +1931,7 @@ struct PartialVecNonZeroSized { struct PartialVecZeroSized { num_t: usize, num_u: usize, - marker_t: InvariantType, - marker_u: InvariantType, + marker: PhantomData<::core::cell::Cell<(T,U)>>, } #[unsafe_destructor] diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 82ccfd0614fd5..cc2324c697cc5 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -859,7 +859,7 @@ pub struct IntoIter { } #[unstable(feature = "collections")] -pub struct Drain<'a, V> { +pub struct Drain<'a, V:'a> { iter: FilterMap< Enumerate>>, fn((usize, Option)) -> Option<(usize, V)>> From b3c00a69f23b68cba2901eb98b3de7dfc6990396 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 10:33:53 -0500 Subject: [PATCH 24/76] Fallout: btree. Rephrase invariant lifetime in terms of PhantomData. --- src/libcollections/btree/map.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 747211e923859..f0e558e6f9105 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -512,13 +512,22 @@ mod stack { use super::super::node::handle; use vec::Vec; + struct InvariantLifetime<'id>( + marker::PhantomData<::core::cell::Cell<&'id ()>>); + + impl<'id> InvariantLifetime<'id> { + fn new() -> InvariantLifetime<'id> { + InvariantLifetime(marker::PhantomData) + } + } + /// A generic mutable reference, identical to `&mut` except for the fact that its lifetime /// parameter is invariant. This means that wherever an `IdRef` is expected, only an `IdRef` /// with the exact requested lifetime can be used. This is in contrast to normal references, /// where `&'static` can be used in any function expecting any lifetime reference. pub struct IdRef<'id, T: 'id> { inner: &'id mut T, - marker: marker::InvariantLifetime<'id> + _marker: InvariantLifetime<'id>, } impl<'id, T> Deref for IdRef<'id, T> { @@ -560,7 +569,7 @@ mod stack { pub struct Pusher<'id, 'a, K:'a, V:'a> { map: &'a mut BTreeMap, stack: Stack, - marker: marker::InvariantLifetime<'id> + _marker: InvariantLifetime<'id>, } impl<'a, K, V> PartialSearchStack<'a, K, V> { @@ -595,11 +604,11 @@ mod stack { let pusher = Pusher { map: self.map, stack: self.stack, - marker: marker::InvariantLifetime + _marker: InvariantLifetime::new(), }; let node = IdRef { inner: unsafe { &mut *self.next }, - marker: marker::InvariantLifetime + _marker: InvariantLifetime::new(), }; closure(pusher, node) From 68ebe640b6c99f53fee53671e09c673c8c17726a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 10:35:56 -0500 Subject: [PATCH 25/76] Fallout: port btree to use Unique, some markers. --- src/libcollections/btree/node.rs | 84 ++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index 24523d4dcc9d3..4d10d99421e22 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -21,10 +21,11 @@ use core::prelude::*; use core::borrow::BorrowFrom; use core::cmp::Ordering::{Greater, Less, Equal}; use core::iter::Zip; +use core::marker::PhantomData; use core::ops::{Deref, DerefMut, Index, IndexMut}; use core::ptr::Unique; use core::{slice, mem, ptr, cmp, num, raw}; -use alloc::heap; +use alloc::heap::{self, EMPTY}; /// Represents the result of an Insertion: either the item fit, or the node had to split pub enum InsertionResult { @@ -57,8 +58,8 @@ pub struct Node { keys: Unique, vals: Unique, - // In leaf nodes, this will be null, and no space will be allocated for edges. - edges: Unique>, + // In leaf nodes, this will be None, and no space will be allocated for edges. + edges: Option>>, // At any given time, there will be `_len` keys, `_len` values, and (in an internal node) // `_len + 1` edges. In a leaf node, there will never be any edges. @@ -278,8 +279,11 @@ impl Drop for RawItems { #[unsafe_destructor] impl Drop for Node { fn drop(&mut self) { - if self.keys.ptr.is_null() { - // We have already cleaned up this node. + if self.keys.is_null() { + // Since we have #[unsafe_no_drop_flag], we have to watch + // out for a null value being stored in self.keys. (Using + // null is technically a violation of the `Unique` + // requirements, though.) return; } @@ -292,7 +296,7 @@ impl Drop for Node { self.destroy(); } - self.keys.ptr = ptr::null_mut(); + self.keys = unsafe { Unique::new(0 as *mut K) }; } } @@ -308,9 +312,9 @@ impl Node { let (vals_offset, edges_offset) = calculate_offsets_generic::(capacity, false); Node { - keys: Unique(buffer as *mut K), - vals: Unique(buffer.offset(vals_offset as isize) as *mut V), - edges: Unique(buffer.offset(edges_offset as isize) as *mut Node), + keys: Unique::new(buffer as *mut K), + vals: Unique::new(buffer.offset(vals_offset as isize) as *mut V), + edges: Some(Unique::new(buffer.offset(edges_offset as isize) as *mut Node)), _len: 0, _capacity: capacity, } @@ -326,9 +330,9 @@ impl Node { let (vals_offset, _) = calculate_offsets_generic::(capacity, true); Node { - keys: Unique(buffer as *mut K), - vals: Unique(unsafe { buffer.offset(vals_offset as isize) as *mut V }), - edges: Unique(ptr::null_mut()), + keys: unsafe { Unique::new(buffer as *mut K) }, + vals: unsafe { Unique::new(buffer.offset(vals_offset as isize) as *mut V) }, + edges: None, _len: 0, _capacity: capacity, } @@ -337,18 +341,18 @@ impl Node { unsafe fn destroy(&mut self) { let (alignment, size) = calculate_allocation_generic::(self.capacity(), self.is_leaf()); - heap::deallocate(self.keys.ptr as *mut u8, size, alignment); + heap::deallocate(*self.keys as *mut u8, size, alignment); } #[inline] pub fn as_slices<'a>(&'a self) -> (&'a [K], &'a [V]) { unsafe {( mem::transmute(raw::Slice { - data: self.keys.ptr, + data: *self.keys as *const K, len: self.len() }), mem::transmute(raw::Slice { - data: self.vals.ptr, + data: *self.vals as *const V, len: self.len() }) )} @@ -367,8 +371,12 @@ impl Node { &[] } else { unsafe { + let data = match self.edges { + None => heap::EMPTY as *const Node, + Some(ref p) => **p as *const Node, + }; mem::transmute(raw::Slice { - data: self.edges.ptr, + data: data, len: self.len() + 1 }) } @@ -524,7 +532,8 @@ impl Clone for Node { #[derive(Copy)] pub struct Handle { node: NodeRef, - index: usize + index: usize, + marker: PhantomData<(Type, NodeType)>, } pub mod handle { @@ -548,8 +557,8 @@ impl Node { // For the B configured as of this writing (B = 6), binary search was *significantly* // worse for usizes. match node.as_slices_internal().search_linear(key) { - (index, true) => Found(Handle { node: node, index: index }), - (index, false) => GoDown(Handle { node: node, index: index }), + (index, true) => Found(Handle { node: node, index: index, marker: PhantomData }), + (index, false) => GoDown(Handle { node: node, index: index, marker: PhantomData }), } } } @@ -586,7 +595,7 @@ impl Node { /// If the node has any children pub fn is_leaf(&self) -> bool { - self.edges.ptr.is_null() + self.edges.is_none() } /// if the node has too few elements @@ -618,7 +627,8 @@ impl Handle where pub fn as_raw(&mut self) -> Handle<*mut Node, Type, NodeType> { Handle { node: &mut *self.node as *mut _, - index: self.index + index: self.index, + marker: PhantomData, } } } @@ -630,7 +640,8 @@ impl Handle<*mut Node, Type, NodeType> { pub unsafe fn from_raw<'a>(&'a self) -> Handle<&'a Node, Type, NodeType> { Handle { node: &*self.node, - index: self.index + index: self.index, + marker: PhantomData, } } @@ -640,7 +651,8 @@ impl Handle<*mut Node, Type, NodeType> { pub unsafe fn from_raw_mut<'a>(&'a mut self) -> Handle<&'a mut Node, Type, NodeType> { Handle { node: &mut *self.node, - index: self.index + index: self.index, + marker: PhantomData, } } } @@ -688,12 +700,14 @@ impl>, Type> Handle Handle where unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node, handle::KV, NodeType> { Handle { node: &mut *self.node, - index: self.index - 1 + index: self.index - 1, + marker: PhantomData, } } @@ -836,7 +851,8 @@ impl Handle where unsafe fn right_kv<'a>(&'a mut self) -> Handle<&'a mut Node, handle::KV, NodeType> { Handle { node: &mut *self.node, - index: self.index + index: self.index, + marker: PhantomData, } } } @@ -876,7 +892,8 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a mut Node, handle::KV, NodeType pub fn into_left_edge(self) -> Handle<&'a mut Node, handle::Edge, NodeType> { Handle { node: &mut *self.node, - index: self.index + index: self.index, + marker: PhantomData, } } } @@ -926,7 +943,8 @@ impl Handle where pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node, handle::Edge, NodeType> { Handle { node: &mut *self.node, - index: self.index + index: self.index, + marker: PhantomData, } } @@ -935,7 +953,8 @@ impl Handle where pub fn right_edge<'a>(&'a mut self) -> Handle<&'a mut Node, handle::Edge, NodeType> { Handle { node: &mut *self.node, - index: self.index + 1 + index: self.index + 1, + marker: PhantomData, } } } @@ -1044,7 +1063,8 @@ impl Node { debug_assert!(index < self.len(), "kv_handle index out of bounds"); Handle { node: self, - index: index + index: index, + marker: PhantomData, } } @@ -1064,7 +1084,7 @@ impl Node { vals: RawItems::from_slice(self.vals()), edges: RawItems::from_slice(self.edges()), - ptr: self.keys.ptr as *mut u8, + ptr: *self.keys as *mut u8, capacity: self.capacity(), is_leaf: self.is_leaf() }, From c2891cc48798908a96d1b3f847d2cf241fcc58bb Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 10:38:21 -0500 Subject: [PATCH 26/76] Fallout: EnumSet, add Marker. --- src/libcollections/enum_set.rs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index d5403ca5d9b19..16041dea7d929 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -14,6 +14,7 @@ //! representation to hold C-like enum variants. use core::prelude::*; +use core::marker; use core::fmt; use core::num::Int; use core::iter::{FromIterator, IntoIterator}; @@ -26,7 +27,8 @@ use core::ops::{Sub, BitOr, BitAnd, BitXor}; pub struct EnumSet { // We must maintain the invariant that no bits are set // for which no variant exists - bits: usize + bits: usize, + marker: marker::PhantomData, } impl Copy for EnumSet {} @@ -86,7 +88,7 @@ impl EnumSet { #[unstable(feature = "collections", reason = "matches collection reform specification, waiting for dust to settle")] pub fn new() -> EnumSet { - EnumSet {bits: 0} + EnumSet {bits: 0, marker: marker::PhantomData} } /// Returns the number of elements in the given `EnumSet`. @@ -130,12 +132,14 @@ impl EnumSet { /// Returns the union of both `EnumSets`. pub fn union(&self, e: EnumSet) -> EnumSet { - EnumSet {bits: self.bits | e.bits} + EnumSet {bits: self.bits | e.bits, + marker: marker::PhantomData} } /// Returns the intersection of both `EnumSets`. pub fn intersection(&self, e: EnumSet) -> EnumSet { - EnumSet {bits: self.bits & e.bits} + EnumSet {bits: self.bits & e.bits, + marker: marker::PhantomData} } /// Adds an enum to the `EnumSet`, and returns `true` if it wasn't there before @@ -175,7 +179,7 @@ impl Sub for EnumSet { type Output = EnumSet; fn sub(self, e: EnumSet) -> EnumSet { - EnumSet {bits: self.bits & !e.bits} + EnumSet {bits: self.bits & !e.bits, marker: marker::PhantomData} } } @@ -183,7 +187,7 @@ impl BitOr for EnumSet { type Output = EnumSet; fn bitor(self, e: EnumSet) -> EnumSet { - EnumSet {bits: self.bits | e.bits} + EnumSet {bits: self.bits | e.bits, marker: marker::PhantomData} } } @@ -191,7 +195,7 @@ impl BitAnd for EnumSet { type Output = EnumSet; fn bitand(self, e: EnumSet) -> EnumSet { - EnumSet {bits: self.bits & e.bits} + EnumSet {bits: self.bits & e.bits, marker: marker::PhantomData} } } @@ -199,7 +203,7 @@ impl BitXor for EnumSet { type Output = EnumSet; fn bitxor(self, e: EnumSet) -> EnumSet { - EnumSet {bits: self.bits ^ e.bits} + EnumSet {bits: self.bits ^ e.bits, marker: marker::PhantomData} } } @@ -207,6 +211,7 @@ impl BitXor for EnumSet { pub struct Iter { index: usize, bits: usize, + marker: marker::PhantomData, } // FIXME(#19839) Remove in favor of `#[derive(Clone)]` @@ -215,13 +220,14 @@ impl Clone for Iter { Iter { index: self.index, bits: self.bits, + marker: marker::PhantomData, } } } impl Iter { fn new(bits: usize) -> Iter { - Iter { index: 0, bits: bits } + Iter { index: 0, bits: bits, marker: marker::PhantomData } } } From 8dbdcdbfb3d09c6d521b275e71370117850c89e2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 10:38:45 -0500 Subject: [PATCH 27/76] Fallout: RingBuf, use Unique. --- src/libcollections/ring_buf.rs | 60 ++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs index 6dcdb21f8000b..6e5970345f1d8 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/ring_buf.rs @@ -28,7 +28,7 @@ use core::marker; use core::mem; use core::num::{Int, UnsignedInt}; use core::ops::{Index, IndexMut}; -use core::ptr; +use core::ptr::{self, Unique}; use core::raw::Slice as RawSlice; use core::hash::{Writer, Hash, Hasher}; @@ -51,7 +51,7 @@ pub struct RingBuf { tail: usize, head: usize, cap: usize, - ptr: *mut T + ptr: Unique, } #[stable(feature = "rust1", since = "1.0.0")] @@ -74,7 +74,7 @@ impl Drop for RingBuf { self.clear(); unsafe { if mem::size_of::() != 0 { - heap::deallocate(self.ptr as *mut u8, + heap::deallocate(*self.ptr as *mut u8, self.cap * mem::size_of::(), mem::min_align_of::()) } @@ -92,13 +92,13 @@ impl RingBuf { /// Turn ptr into a slice #[inline] unsafe fn buffer_as_slice(&self) -> &[T] { - mem::transmute(RawSlice { data: self.ptr, len: self.cap }) + mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap }) } /// Turn ptr into a mut slice #[inline] unsafe fn buffer_as_mut_slice(&mut self) -> &mut [T] { - mem::transmute(RawSlice { data: self.ptr, len: self.cap }) + mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap }) } /// Moves an element out of the buffer @@ -165,21 +165,21 @@ impl RingBuf { let size = cap.checked_mul(mem::size_of::()) .expect("capacity overflow"); - let ptr = if mem::size_of::() != 0 { - unsafe { + let ptr = unsafe { + if mem::size_of::() != 0 { let ptr = heap::allocate(size, mem::min_align_of::()) as *mut T;; if ptr.is_null() { ::alloc::oom() } - ptr + Unique::new(ptr) + } else { + Unique::new(heap::EMPTY as *mut T) } - } else { - heap::EMPTY as *mut T }; RingBuf { tail: 0, head: 0, cap: cap, - ptr: ptr + ptr: ptr, } } @@ -335,11 +335,12 @@ impl RingBuf { let new = count.checked_mul(mem::size_of::()) .expect("capacity overflow"); unsafe { - self.ptr = heap::reallocate(self.ptr as *mut u8, - old, - new, - mem::min_align_of::()) as *mut T; - if self.ptr.is_null() { ::alloc::oom() } + let ptr = heap::reallocate(*self.ptr as *mut u8, + old, + new, + mem::min_align_of::()) as *mut T; + if ptr.is_null() { ::alloc::oom() } + self.ptr = Unique::new(ptr); } } @@ -453,11 +454,12 @@ impl RingBuf { let old = self.cap * mem::size_of::(); let new_size = target_cap * mem::size_of::(); unsafe { - self.ptr = heap::reallocate(self.ptr as *mut u8, - old, - new_size, - mem::min_align_of::()) as *mut T; - if self.ptr.is_null() { ::alloc::oom() } + let ptr = heap::reallocate(*self.ptr as *mut u8, + old, + new_size, + mem::min_align_of::()) as *mut T; + if ptr.is_null() { ::alloc::oom() } + self.ptr = Unique::new(ptr); } } self.cap = target_cap; @@ -539,8 +541,8 @@ impl RingBuf { tail: self.tail, head: self.head, cap: self.cap, - ptr: self.ptr, - marker: marker::ContravariantLifetime, + ptr: *self.ptr, + marker: marker::PhantomData, } } @@ -1336,7 +1338,7 @@ impl RingBuf { // `at` lies in the first half. let amount_in_first = first_len - at; - ptr::copy_nonoverlapping_memory(other.ptr, + ptr::copy_nonoverlapping_memory(*other.ptr, first_half.as_ptr().offset(at as isize), amount_in_first); @@ -1349,7 +1351,7 @@ impl RingBuf { // in the first half. let offset = at - first_len; let amount_in_second = second_len - offset; - ptr::copy_nonoverlapping_memory(other.ptr, + ptr::copy_nonoverlapping_memory(*other.ptr, second_half.as_ptr().offset(offset as isize), amount_in_second); } @@ -1518,7 +1520,7 @@ pub struct IterMut<'a, T:'a> { tail: usize, head: usize, cap: usize, - marker: marker::ContravariantLifetime<'a>, + marker: marker::PhantomData<&'a mut T>, } #[stable(feature = "rust1", since = "1.0.0")] @@ -1986,9 +1988,9 @@ mod tests { #[derive(Clone, PartialEq, Debug)] enum Taggypar { - Onepar(i32), - Twopar(i32, i32), - Threepar(i32, i32, i32), + Onepar(T), + Twopar(T, T), + Threepar(T, T, T), } #[derive(Clone, PartialEq, Debug)] From 2bcf3a4cd15f706dcb07b1835babeea15b8aa8c1 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 10:39:32 -0500 Subject: [PATCH 28/76] Fallout: arena needs to use phantomdata since invariantlifetime is gone --- src/libarena/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 4cd3d587580f0..b43f9adfb26d9 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -96,7 +96,7 @@ pub struct Arena<'longer_than_self> { head: RefCell, copy_head: RefCell, chunks: RefCell>, - _invariant: marker::InvariantLifetime<'longer_than_self>, + _marker: marker::PhantomData<*mut &'longer_than_self()>, } impl<'a> Arena<'a> { @@ -111,7 +111,7 @@ impl<'a> Arena<'a> { head: RefCell::new(chunk(initial_size, false)), copy_head: RefCell::new(chunk(initial_size, true)), chunks: RefCell::new(Vec::new()), - _invariant: marker::InvariantLifetime, + _marker: marker::PhantomData, } } } @@ -361,6 +361,8 @@ pub struct TypedArena { } struct TypedArenaChunk { + marker: marker::PhantomData, + /// Pointer to the next arena segment. next: *mut TypedArenaChunk, From 1735e41d1cbbe0666e188ccf3a064e5c8afb482c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 10:47:02 -0500 Subject: [PATCH 29/76] Fallout: AtomicPtr needs phantom data to indicate that it contains an unsafe pointer. --- src/libcore/atomic.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs index 05d864accc130..6afe5b2257d27 100644 --- a/src/libcore/atomic.rs +++ b/src/libcore/atomic.rs @@ -76,6 +76,7 @@ use marker::Sync; use intrinsics; use cell::UnsafeCell; +use marker::PhantomData; /// A boolean type which can be safely shared between threads. #[stable(feature = "rust1", since = "1.0.0")] @@ -105,6 +106,7 @@ unsafe impl Sync for AtomicUsize {} #[stable(feature = "rust1", since = "1.0.0")] pub struct AtomicPtr { p: UnsafeCell, + _marker: PhantomData<*mut T>, } unsafe impl Sync for AtomicPtr {} @@ -791,7 +793,8 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn new(p: *mut T) -> AtomicPtr { - AtomicPtr { p: UnsafeCell::new(p as usize) } + AtomicPtr { p: UnsafeCell::new(p as usize), + _marker: PhantomData } } /// Loads a value from the pointer. From d801a4da7cc8672c3b7655ccad218ab892b8dd9b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 10:47:38 -0500 Subject: [PATCH 30/76] Fallout: iter, add markers or other changes such that all type parameters are used. --- src/libcore/iter.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index fffba1561a380..7a54aeb6b9c57 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -62,6 +62,7 @@ use clone::Clone; use cmp; use cmp::Ord; use default::Default; +use marker; use mem; use num::{ToPrimitive, Int}; use ops::{Add, Deref, FnMut}; @@ -947,7 +948,7 @@ pub trait IteratorExt: Iterator + Sized { FromB: Default + Extend, Self: Iterator, { - struct SizeHint(usize, Option); + struct SizeHint(usize, Option, marker::PhantomData); impl Iterator for SizeHint { type Item = A; @@ -961,8 +962,8 @@ pub trait IteratorExt: Iterator + Sized { let mut ts: FromA = Default::default(); let mut us: FromB = Default::default(); - ts.extend(SizeHint(lo, hi)); - us.extend(SizeHint(lo, hi)); + ts.extend(SizeHint(lo, hi, marker::PhantomData)); + us.extend(SizeHint(lo, hi, marker::PhantomData)); for (t, u) in self { ts.extend(Some(t).into_iter()); @@ -2047,8 +2048,8 @@ pub struct Scan { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Scan where - F: FnMut(&mut St, I::Item) -> Option, +impl, St, F> Iterator for Scan where + F: FnMut(&mut St, A) -> Option, { type Item = B; From ef42c2befd9451cd913de60539487a483ae9deac Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 10:17:02 -0500 Subject: [PATCH 31/76] Fallout: docs, elided examples often elided too much. --- src/doc/reference.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 00ed5d4562b11..0d65c97180460 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -576,7 +576,7 @@ the final namespace qualifier is omitted. Two examples of paths with type arguments: ``` -# struct HashMap; +# struct HashMap(K,V); # fn f() { # fn id(t: T) -> T { t } type T = HashMap; // Type arguments used in a type expression @@ -1603,7 +1603,7 @@ pointer values (pointing to a type for which an implementation of the given trait is in scope) to pointers to the trait name, used as a type. ``` -# trait Shape { } +# trait Shape { fn dummy(&self) { } } # impl Shape for i32 { } # let mycircle = 0i32; let myshape: Box = Box::new(mycircle) as Box; @@ -1634,8 +1634,8 @@ let x: f64 = Num::from_i32(42); Traits may inherit from other traits. For example, in ``` -trait Shape { fn area() -> f64; } -trait Circle : Shape { fn radius() -> f64; } +trait Shape { fn area(&self) -> f64; } +trait Circle : Shape { fn radius(&self) -> f64; } ``` the syntax `Circle : Shape` means that types that implement `Circle` must also @@ -1729,7 +1729,7 @@ type parameters taken by the trait it implements. Implementation parameters are written after the `impl` keyword. ``` -# trait Seq { } +# trait Seq { fn dummy(&self, _: T) { } } impl Seq for Vec { /* ... */ } From 872ce479550a3d805babb0ca409dfc3cf6f52309 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 10:29:52 -0500 Subject: [PATCH 32/76] Fallout: tests. As tests frequently elide things, lots of changes here. Some of this may have been poorly rebased, though I tried to be careful and preserve the spirit of the test. --- src/libcoretest/mem.rs | 2 +- src/test/auxiliary/coherence-orphan-lib.rs | 2 +- src/test/auxiliary/default_type_params_xc.rs | 3 +- src/test/auxiliary/inner_static.rs | 12 ++--- src/test/auxiliary/issue-14421.rs | 5 +- src/test/auxiliary/issue-16643.rs | 2 +- src/test/auxiliary/issue-17662.rs | 2 +- src/test/auxiliary/issue-2380.rs | 5 +- src/test/auxiliary/issue-2526.rs | 8 ++- src/test/auxiliary/issue_20389.rs | 1 + src/test/auxiliary/issue_3907.rs | 4 +- src/test/auxiliary/issue_8401.rs | 4 +- src/test/auxiliary/issue_9123.rs | 1 + src/test/auxiliary/lang-item-public.rs | 10 +++- src/test/auxiliary/lint_stability.rs | 2 +- src/test/auxiliary/nested_item.rs | 2 +- .../auxiliary/orphan_check_diagnostics.rs | 2 +- src/test/auxiliary/overloaded_autoderef_xc.rs | 5 +- src/test/auxiliary/private_trait_xc.rs | 2 +- src/test/auxiliary/svh-a-base.rs | 6 ++- src/test/auxiliary/svh-a-change-lit.rs | 6 ++- .../auxiliary/svh-a-change-significant-cfg.rs | 6 ++- .../auxiliary/svh-a-change-trait-bound.rs | 6 ++- src/test/auxiliary/svh-a-change-type-arg.rs | 6 ++- src/test/auxiliary/svh-a-change-type-ret.rs | 6 ++- .../auxiliary/svh-a-change-type-static.rs | 6 ++- src/test/auxiliary/svh-a-comment.rs | 6 ++- src/test/auxiliary/svh-a-doc.rs | 6 ++- src/test/auxiliary/svh-a-macro.rs | 6 ++- src/test/auxiliary/svh-a-no-change.rs | 6 ++- src/test/auxiliary/svh-a-redundant-cfg.rs | 6 ++- src/test/auxiliary/svh-a-whitespace.rs | 6 ++- .../trait_bounds_on_structs_and_enums_xc.rs | 4 +- src/test/auxiliary/trait_impl_conflict.rs | 2 +- src/test/auxiliary/use_from_trait_xc.rs | 2 +- ...ed-types-ICE-when-projecting-out-of-err.rs | 6 ++- .../associated-types-coherence-failure.rs | 3 +- .../associated-types-eq-expr-path.rs | 2 +- .../associated-types-issue-17359.rs | 2 +- ...sociated-types-multiple-types-one-trait.rs | 2 +- ...associated-types-no-suitable-supertrait.rs | 2 +- .../compile-fail/associated-types-path-2.rs | 2 + .../associated-types-unconstrained.rs | 2 +- .../compile-fail/bad-mid-path-type-params.rs | 7 --- src/test/compile-fail/bad-sized.rs | 2 +- ...nket-conflicts-with-blanket-implemented.rs | 5 +- ...et-conflicts-with-blanket-unimplemented.rs | 4 +- ...herence-conflicting-negative-trait-impl.rs | 8 +-- src/test/compile-fail/cross-borrow-trait.rs | 2 +- .../compile-fail/destructure-trait-ref.rs | 2 +- src/test/compile-fail/dst-bad-coerce1.rs | 2 +- src/test/compile-fail/dst-bad-coerce2.rs | 2 +- src/test/compile-fail/dst-bad-coerce3.rs | 2 +- src/test/compile-fail/dst-bad-coercions.rs | 4 +- .../dst-object-from-unsized-type.rs | 2 +- .../compile-fail/exclusive-drop-and-copy.rs | 2 +- .../generic-impl-less-params-with-defaults.rs | 7 ++- .../generic-impl-more-params-with-defaults.rs | 7 ++- .../generic-lifetime-trait-impl.rs | 5 +- .../generic-type-less-params-with-defaults.rs | 5 +- .../generic-type-more-params-with-defaults.rs | 5 +- .../generic-type-params-name-repr.rs | 8 +-- src/test/compile-fail/issue-11515.rs | 2 +- src/test/compile-fail/issue-13853-2.rs | 4 +- src/test/compile-fail/issue-13853-3.rs | 5 +- src/test/compile-fail/issue-13853.rs | 4 +- src/test/compile-fail/issue-14285.rs | 4 +- src/test/compile-fail/issue-14853.rs | 3 +- src/test/compile-fail/issue-16747.rs | 4 +- src/test/compile-fail/issue-17431-4.rs | 4 +- src/test/compile-fail/issue-17431-5.rs | 4 +- src/test/compile-fail/issue-17551.rs | 6 ++- src/test/compile-fail/issue-18107.rs | 4 +- src/test/compile-fail/issue-18611.rs | 4 +- src/test/compile-fail/issue-18783.rs | 1 + src/test/compile-fail/issue-18819.rs | 4 +- src/test/compile-fail/issue-19660.rs | 6 ++- src/test/compile-fail/issue-2063.rs | 3 +- src/test/compile-fail/issue-20831-debruijn.rs | 5 +- src/test/compile-fail/issue-2611-4.rs | 4 +- src/test/compile-fail/issue-3008-3.rs | 4 +- src/test/compile-fail/issue-4972.rs | 4 +- src/test/compile-fail/issue-5035-2.rs | 4 +- src/test/compile-fail/issue-5543.rs | 4 +- src/test/compile-fail/issue-5883.rs | 6 ++- src/test/compile-fail/issue-6458.rs | 6 ++- src/test/compile-fail/issue-7575.rs | 8 +-- src/test/compile-fail/issue-8727.rs | 10 ++-- src/test/compile-fail/kindck-copy.rs | 4 +- .../compile-fail/kindck-impl-type-params-2.rs | 4 +- .../compile-fail/kindck-impl-type-params.rs | 20 +++++--- src/test/compile-fail/kindck-send-object.rs | 4 +- src/test/compile-fail/kindck-send-object1.rs | 4 +- src/test/compile-fail/kindck-send-object2.rs | 4 +- ...me-inference-give-expl-lifetime-param-3.rs | 4 +- ...time-inference-give-expl-lifetime-param.rs | 4 +- src/test/compile-fail/lint-missing-doc.rs | 20 +++++--- .../compile-fail/lint-non-camel-case-types.rs | 1 + src/test/compile-fail/lint-stability.rs | 4 +- .../lint-visible-private-types.rs | 8 +-- .../compile-fail/liveness-use-after-send.rs | 4 +- src/test/compile-fail/map-types.rs | 5 +- .../method-ambig-one-trait-coerce.rs | 50 ------------------- .../object-does-not-impl-trait.rs | 3 +- .../object-lifetime-default-mybox.rs | 1 - .../compile-fail/object-safety-no-static.rs | 2 +- .../compile-fail/on-unimplemented-bad-anno.rs | 18 +++++-- src/test/compile-fail/on-unimplemented.rs | 6 ++- .../compile-fail/orphan-check-diagnostics.rs | 2 +- .../compile-fail/priv-in-bad-locations.rs | 4 +- src/test/compile-fail/privacy-ns2.rs | 8 +-- src/test/compile-fail/privacy1.rs | 8 ++- src/test/compile-fail/privacy4.rs | 8 ++- .../region-object-lifetime-in-coercion.rs | 2 +- ...ssoc-type-region-bound-in-trait-not-met.rs | 5 +- ...ssoc-type-static-bound-in-trait-not-met.rs | 5 +- .../regions-bound-missing-bound-in-impl.rs | 5 +- ...nded-method-type-parameters-trait-bound.rs | 6 --- ...gions-close-associated-type-into-object.rs | 4 +- .../regions-close-object-into-object-1.rs | 9 ++-- .../regions-close-object-into-object-2.rs | 6 ++- .../regions-close-object-into-object-3.rs | 6 ++- .../regions-close-object-into-object-4.rs | 6 ++- .../regions-close-over-borrowed-ref-in-obj.rs | 4 +- .../regions-close-param-into-object.rs | 2 +- ...egions-infer-contravariance-due-to-decl.rs | 2 +- .../regions-infer-covariance-due-to-decl.rs | 2 +- .../regions-infer-invariance-due-to-decl.rs | 2 +- src/test/compile-fail/required-lang-item.rs | 6 ++- .../compile-fail/shadowed-type-parameter.rs | 6 ++- .../slightly-nice-generic-literal-messages.rs | 6 ++- src/test/compile-fail/staticness-mismatch.rs | 2 +- .../trait-as-struct-constructor.rs | 2 +- .../compile-fail/trait-bounds-cant-coerce.rs | 1 + .../trait-bounds-impl-comparison-1.rs | 14 ++++-- .../trait-bounds-impl-comparison-2.rs | 4 +- .../trait-bounds-not-on-bare-trait.rs | 1 + ...rait-bounds-on-structs-and-enums-locals.rs | 4 +- ...rait-bounds-on-structs-and-enums-static.rs | 4 +- .../trait-bounds-on-structs-and-enums.rs | 10 ++-- src/test/compile-fail/trait-bounds-sugar.rs | 3 +- src/test/compile-fail/trait-impl-1.rs | 4 +- src/test/compile-fail/trait-object-safety.rs | 1 + .../trait-static-method-generic-inference.rs | 1 + .../typeck-negative-impls-builtin.rs | 4 +- .../typeck_type_placeholder_mismatch.rs | 10 ++-- .../unboxed-closure-feature-gate.rs | 4 ++ .../unboxed-closure-sugar-default.rs | 2 +- .../unboxed-closure-sugar-equiv.rs | 4 +- .../unboxed-closure-sugar-lifetime-elision.rs | 4 +- .../unboxed-closure-sugar-region.rs | 2 +- ...oxed-closures-recursive-fn-using-fn-mut.rs | 6 +-- src/test/compile-fail/unnecessary-private.rs | 4 +- .../unsized-inherent-impl-self-type.rs | 2 +- .../unsized-trait-impl-self-type.rs | 3 +- .../unsized-trait-impl-trait-arg.rs | 3 +- src/test/compile-fail/unsized3.rs | 5 +- src/test/compile-fail/unsized6.rs | 3 +- src/test/compile-fail/unsized7.rs | 8 ++- src/test/compile-fail/unused-attr.rs | 4 +- src/test/compile-fail/useless-priv.rs | 8 +-- src/test/compile-fail/useless-priv2.rs | 6 ++- .../compile-fail/variance-regions-direct.rs | 1 + .../compile-fail/variance-regions-indirect.rs | 4 ++ .../variance-trait-object-bound.rs | 2 +- .../visible-private-types-generics.rs | 4 +- .../visible-private-types-supertrait.rs | 4 +- .../where-clause-method-substituion.rs | 4 +- .../where-clauses-not-parameter.rs | 4 +- src/test/debuginfo/type-names.rs | 17 ++++--- src/test/pretty/empty-impl.rs | 4 +- src/test/pretty/path-type-bounds.rs | 4 +- src/test/run-fail/bug-811.rs | 4 ++ src/test/run-make/rustdoc-json/foo.rs | 2 +- .../run-make/rustdoc-negative-impl/foo.rs | 2 +- .../run-make/rustdoc-search-index/index.rs | 2 +- src/test/run-make/rustdoc-smoke/foo.rs | 2 +- .../run-make/rustdoc-viewpath-self/foo.rs | 2 +- src/test/run-make/rustdoc-where/foo.rs | 15 +++--- src/test/run-make/save-analysis/foo.rs | 1 + src/test/run-make/simd-ffi/simd.rs | 8 ++- .../run-make/symbols-are-reasonable/lib.rs | 2 +- src/test/run-make/target-specs/foo.rs | 8 ++- .../cleanup-auto-borrow-obj.rs | 2 +- src/test/run-pass-valgrind/dst-dtor-1.rs | 2 +- src/test/run-pass/associated-types-basic.rs | 4 +- .../associated-types-conditional-dispatch.rs | 7 ++- .../run-pass/associated-types-issue-20371.rs | 4 +- .../run-pass/associated-types-issue-21212.rs | 3 +- .../associated-types-nested-projections.rs | 5 +- ...iated-types-normalize-in-bounds-binding.rs | 6 ++- ...sociated-types-normalize-in-bounds-ufcs.rs | 10 ++-- .../associated-types-normalize-in-bounds.rs | 10 ++-- ...ociated-types-normalize-unifield-struct.rs | 5 +- ...ypes-projection-from-known-type-in-impl.rs | 2 + ...ociated-types-projection-in-object-type.rs | 2 + ...sociated-types-projection-in-supertrait.rs | 2 + ...ciated-types-projection-in-where-clause.rs | 2 + .../associated-types-ref-in-struct-literal.rs | 2 + .../associated-types-resolve-lifetime.rs | 2 + .../associated-types-struct-field-named.rs | 2 + .../associated-types-struct-field-numbered.rs | 2 + .../run-pass/associated-types-sugar-path.rs | 3 +- src/test/run-pass/borrowck-trait-lifetime.rs | 5 +- src/test/run-pass/bug-7295.rs | 6 +-- .../builtin-superkinds-in-metadata.rs | 1 + .../builtin-superkinds-phantom-typaram.rs | 6 ++- src/test/run-pass/class-typarams.rs | 7 ++- src/test/run-pass/dst-coercions.rs | 2 +- src/test/run-pass/enum-null-pointer-opt.rs | 2 +- src/test/run-pass/explicit-self-generic.rs | 8 ++- src/test/run-pass/export-non-interference.rs | 14 ------ ...generic-default-type-params-cross-crate.rs | 10 ++-- src/test/run-pass/hrtb-opt-in-copy.rs | 4 +- src/test/run-pass/inner-static.rs | 6 +-- src/test/run-pass/issue-10456.rs | 4 +- src/test/run-pass/issue-10802.rs | 2 +- src/test/run-pass/issue-10902.rs | 4 +- src/test/run-pass/issue-11205.rs | 2 +- src/test/run-pass/issue-11384.rs | 2 +- src/test/run-pass/issue-11612.rs | 2 +- src/test/run-pass/issue-11677.rs | 9 +++- src/test/run-pass/issue-13105.rs | 4 +- src/test/run-pass/issue-14399.rs | 2 +- src/test/run-pass/issue-14589.rs | 7 +-- src/test/run-pass/issue-14958.rs | 2 +- src/test/run-pass/issue-14959.rs | 8 +-- src/test/run-pass/issue-15858.rs | 12 ++--- src/test/run-pass/issue-16596.rs | 2 +- src/test/run-pass/issue-16643.rs | 2 +- src/test/run-pass/issue-17662.rs | 6 ++- src/test/run-pass/issue-17732.rs | 3 +- src/test/run-pass/issue-17771.rs | 2 +- src/test/run-pass/issue-17816.rs | 6 ++- src/test/run-pass/issue-17904.rs | 4 +- src/test/run-pass/issue-18232.rs | 4 +- src/test/run-pass/issue-18906.rs | 2 +- src/test/run-pass/issue-19121.rs | 2 + src/test/run-pass/issue-19129-2.rs | 2 +- src/test/run-pass/issue-19135.rs | 6 ++- src/test/run-pass/issue-19358.rs | 2 +- src/test/run-pass/issue-19398.rs | 4 +- src/test/run-pass/issue-19479.rs | 6 ++- src/test/run-pass/issue-19631.rs | 1 + src/test/run-pass/issue-19632.rs | 1 + src/test/run-pass/issue-20055-box-trait.rs | 4 +- src/test/run-pass/issue-20343.rs | 2 +- src/test/run-pass/issue-20763-1.rs | 5 +- src/test/run-pass/issue-20763-2.rs | 5 +- src/test/run-pass/issue-21363.rs | 1 + src/test/run-pass/issue-21909.rs | 6 ++- src/test/run-pass/issue-2311-2.rs | 5 +- src/test/run-pass/issue-2311.rs | 2 +- src/test/run-pass/issue-2312.rs | 2 +- src/test/run-pass/issue-2611-3.rs | 4 +- src/test/run-pass/issue-2734.rs | 4 +- src/test/run-pass/issue-2735.rs | 4 +- src/test/run-pass/issue-4107.rs | 12 ++--- src/test/run-pass/issue-5192.rs | 1 + src/test/run-pass/issue-5708.rs | 4 +- src/test/run-pass/issue-6128.rs | 4 ++ src/test/run-pass/issue-6318.rs | 4 +- src/test/run-pass/issue-7575.rs | 1 + ...7673-cast-generically-implemented-trait.rs | 5 +- src/test/run-pass/issue-7911.rs | 4 +- src/test/run-pass/issue-8248.rs | 4 +- src/test/run-pass/issue-8249.rs | 4 +- src/test/run-pass/issue-9719.rs | 8 ++- src/test/run-pass/lint-cstack.rs | 2 +- .../method-early-bound-lifetimes-on-self.rs | 8 ++- .../run-pass/method-recursive-blanket-impl.rs | 8 +-- ...nomorphized-callees-with-ty-params-3314.rs | 3 +- .../run-pass/overloaded-autoderef-vtable.rs | 6 ++- .../overloaded-calls-param-vtables.rs | 5 +- .../parameterized-trait-with-bounds.rs | 8 +-- src/test/run-pass/privacy-ns.rs | 3 ++ .../regions-assoc-type-static-bound.rs | 5 +- .../regions-bound-lists-feature-gate-2.rs | 4 +- .../regions-bound-lists-feature-gate.rs | 5 +- ...egions-early-bound-lifetime-in-assoc-fn.rs | 6 ++- .../regions-early-bound-trait-param.rs | 6 +-- src/test/run-pass/regions-infer-bivariance.rs | 28 ----------- .../regions-no-bound-in-argument-cleanup.rs | 4 +- .../regions-no-variance-from-fn-generics.rs | 10 +++- src/test/run-pass/self-impl.rs | 1 + src/test/run-pass/simple-match-generic-tag.rs | 9 ++-- src/test/run-pass/syntax-trait-polarity.rs | 6 +-- src/test/run-pass/trailing-comma.rs | 4 +- src/test/run-pass/trait-bounds-basic.rs | 2 +- .../trait-bounds-on-structs-and-enums.rs | 6 +-- src/test/run-pass/trait-bounds-recursion.rs | 8 +-- .../trait-default-method-bound-subst4.rs | 1 + src/test/run-pass/trait-impl.rs | 3 +- src/test/run-pass/trait-inheritance-num2.rs | 3 +- .../run-pass/trait-inheritance-static2.rs | 4 +- src/test/run-pass/trait-object-generics.rs | 11 ++-- .../trait-static-method-overwriting.rs | 10 ++-- .../unboxed-closures-infer-recursive-fn.rs | 6 +-- src/test/run-pass/unique-object-move.rs | 2 +- src/test/run-pass/unsized.rs | 24 +++++---- src/test/run-pass/unsized2.rs | 12 +++-- .../visible-private-types-feature-gate.rs | 2 +- .../where-clause-bounds-inconsistency.rs | 4 +- .../where-clause-early-bound-lifetimes.rs | 2 +- .../where-clause-method-substituion.rs | 4 +- src/test/run-pass/where-for-self.rs | 10 +++- 306 files changed, 915 insertions(+), 580 deletions(-) delete mode 100644 src/test/compile-fail/method-ambig-one-trait-coerce.rs delete mode 100644 src/test/run-pass/export-non-interference.rs delete mode 100644 src/test/run-pass/regions-infer-bivariance.rs diff --git a/src/libcoretest/mem.rs b/src/libcoretest/mem.rs index 421ce76caaf46..5aeb330b78b54 100644 --- a/src/libcoretest/mem.rs +++ b/src/libcoretest/mem.rs @@ -92,7 +92,7 @@ fn test_transmute_copy() { #[test] fn test_transmute() { - trait Foo {} + trait Foo { fn dummy(&self) { } } impl Foo for int {} let a = box 100 as Box; diff --git a/src/test/auxiliary/coherence-orphan-lib.rs b/src/test/auxiliary/coherence-orphan-lib.rs index 2e5d18b58f22f..cc42b288e6638 100644 --- a/src/test/auxiliary/coherence-orphan-lib.rs +++ b/src/test/auxiliary/coherence-orphan-lib.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait TheTrait { +pub trait TheTrait : ::std::marker::PhantomFn { fn the_fn(&self); } diff --git a/src/test/auxiliary/default_type_params_xc.rs b/src/test/auxiliary/default_type_params_xc.rs index d12f716decf99..0a65174911ec7 100644 --- a/src/test/auxiliary/default_type_params_xc.rs +++ b/src/test/auxiliary/default_type_params_xc.rs @@ -12,4 +12,5 @@ pub struct Heap; pub struct FakeHeap; -pub struct FakeVec; +pub struct FakeVec { pub f: Option<(T,A)> } + diff --git a/src/test/auxiliary/inner_static.rs b/src/test/auxiliary/inner_static.rs index 94acea0661838..ca5c6072cb371 100644 --- a/src/test/auxiliary/inner_static.rs +++ b/src/test/auxiliary/inner_static.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub struct A; -pub struct B; +pub struct A { pub v: T } +pub struct B { pub v: T } pub mod test { - pub struct A; + pub struct A { pub v: T } impl A { pub fn foo(&self) -> int { @@ -52,9 +52,9 @@ impl B { } pub fn foo() -> int { - let a = A::<()>; - let b = B::<()>; - let c = test::A::<()>; + let a = A { v: () }; + let b = B { v: () }; + let c = test::A { v: () }; return a.foo() + a.bar() + b.foo() + b.bar() + c.foo() + c.bar(); diff --git a/src/test/auxiliary/issue-14421.rs b/src/test/auxiliary/issue-14421.rs index 7c69cba179ca1..a48088609f982 100644 --- a/src/test/auxiliary/issue-14421.rs +++ b/src/test/auxiliary/issue-14421.rs @@ -10,6 +10,7 @@ #![crate_type="lib"] #![deny(warnings)] +#![allow(dead_code)] pub use src::aliases::B; pub use src::hidden_core::make; @@ -23,9 +24,9 @@ mod src { pub mod hidden_core { use super::aliases::B; - pub struct A; + pub struct A { t: T } - pub fn make() -> B { A } + pub fn make() -> B { A { t: 1.0 } } impl A { pub fn foo(&mut self) { println!("called foo"); } diff --git a/src/test/auxiliary/issue-16643.rs b/src/test/auxiliary/issue-16643.rs index c5b3fceaf4a5f..b590160a0c2ab 100644 --- a/src/test/auxiliary/issue-16643.rs +++ b/src/test/auxiliary/issue-16643.rs @@ -10,7 +10,7 @@ #![crate_type = "lib"] -pub struct TreeBuilder; +pub struct TreeBuilder { pub h: H } impl TreeBuilder { pub fn process_token(&mut self) { diff --git a/src/test/auxiliary/issue-17662.rs b/src/test/auxiliary/issue-17662.rs index be10ca1dd8fd8..fb55a077005eb 100644 --- a/src/test/auxiliary/issue-17662.rs +++ b/src/test/auxiliary/issue-17662.rs @@ -11,7 +11,7 @@ #![crate_type = "lib"] pub trait Foo<'a, T> { - fn foo(&self) -> T; + fn foo(&'a self) -> T; } pub fn foo<'a, T>(x: &'a Foo<'a, T>) -> T { diff --git a/src/test/auxiliary/issue-2380.rs b/src/test/auxiliary/issue-2380.rs index 8eb6cd6e26318..96f33f97a6969 100644 --- a/src/test/auxiliary/issue-2380.rs +++ b/src/test/auxiliary/issue-2380.rs @@ -14,7 +14,10 @@ #![allow(unknown_features)] #![feature(box_syntax)] -pub trait i { } +pub trait i +{ + fn dummy(&self, t: T) -> T { panic!() } +} pub fn f() -> Box+'static> { impl i for () { } diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs index e3ce4e8f6565a..89b3b56121a16 100644 --- a/src/test/auxiliary/issue-2526.rs +++ b/src/test/auxiliary/issue-2526.rs @@ -13,8 +13,11 @@ #![feature(unsafe_destructor)] +use std::marker; + struct arc_destruct { - _data: int, + _data: int, + _marker: marker::PhantomData } #[unsafe_destructor] @@ -24,7 +27,8 @@ impl Drop for arc_destruct { fn arc_destruct(data: int) -> arc_destruct { arc_destruct { - _data: data + _data: data, + _marker: marker::PhantomData } } diff --git a/src/test/auxiliary/issue_20389.rs b/src/test/auxiliary/issue_20389.rs index 7a378b06df9e1..4ce7e3079e330 100644 --- a/src/test/auxiliary/issue_20389.rs +++ b/src/test/auxiliary/issue_20389.rs @@ -10,4 +10,5 @@ pub trait T { type C; + fn dummy(&self) { } } diff --git a/src/test/auxiliary/issue_3907.rs b/src/test/auxiliary/issue_3907.rs index 2e254e5431d53..545e15fe1664d 100644 --- a/src/test/auxiliary/issue_3907.rs +++ b/src/test/auxiliary/issue_3907.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait Foo { +use std::marker::MarkerTrait; + +pub trait Foo : MarkerTrait { fn bar(); } diff --git a/src/test/auxiliary/issue_8401.rs b/src/test/auxiliary/issue_8401.rs index 0831993119ae8..9006a5d1775f7 100644 --- a/src/test/auxiliary/issue_8401.rs +++ b/src/test/auxiliary/issue_8401.rs @@ -12,7 +12,9 @@ use std::mem; -trait A {} +trait A { + fn dummy(&self) { } +} struct B; impl A for B {} diff --git a/src/test/auxiliary/issue_9123.rs b/src/test/auxiliary/issue_9123.rs index 000cc100a12f3..4f2792aebcd24 100644 --- a/src/test/auxiliary/issue_9123.rs +++ b/src/test/auxiliary/issue_9123.rs @@ -15,5 +15,6 @@ pub trait X { fn f() { } f(); } + fn dummy(&self) { } } diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs index 834667968c85b..b9cc20b63cc56 100644 --- a/src/test/auxiliary/lang-item-public.rs +++ b/src/test/auxiliary/lang-item-public.rs @@ -12,8 +12,12 @@ #![no_std] #![feature(lang_items)] +#[lang="phantom_fn"] +pub trait PhantomFn { } +impl PhantomFn for U { } + #[lang="sized"] -pub trait Sized {} +pub trait Sized : PhantomFn {} #[lang="panic"] fn panic(_: &(&'static str, &'static str, uint)) -> ! { loop {} } @@ -25,6 +29,8 @@ extern fn stack_exhausted() {} extern fn eh_personality() {} #[lang="copy"] -pub trait Copy {} +pub trait Copy : PhantomFn { + // Empty. +} diff --git a/src/test/auxiliary/lint_stability.rs b/src/test/auxiliary/lint_stability.rs index 01b2b748ba9d8..fb535eb8336f9 100644 --- a/src/test/auxiliary/lint_stability.rs +++ b/src/test/auxiliary/lint_stability.rs @@ -96,7 +96,7 @@ pub trait Trait { impl Trait for MethodTester {} #[unstable(feature = "test_feature")] -pub trait UnstableTrait {} +pub trait UnstableTrait { fn dummy(&self) { } } #[stable(feature = "test_feature", since = "1.0.0")] #[deprecated(since = "1.0.0")] diff --git a/src/test/auxiliary/nested_item.rs b/src/test/auxiliary/nested_item.rs index 21784bda27a8f..fc1bea5a9fd41 100644 --- a/src/test/auxiliary/nested_item.rs +++ b/src/test/auxiliary/nested_item.rs @@ -25,7 +25,7 @@ impl Foo { } // issue 8134 -pub struct Parser; +pub struct Parser(T); impl> Parser { fn in_doctype(&mut self) { static DOCTYPEPattern: [char; 6] = ['O', 'C', 'T', 'Y', 'P', 'E']; diff --git a/src/test/auxiliary/orphan_check_diagnostics.rs b/src/test/auxiliary/orphan_check_diagnostics.rs index 7647f159401a7..cf3e9903b5ad0 100644 --- a/src/test/auxiliary/orphan_check_diagnostics.rs +++ b/src/test/auxiliary/orphan_check_diagnostics.rs @@ -8,4 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait RemoteTrait {} +pub trait RemoteTrait { fn dummy(&self) { } } diff --git a/src/test/auxiliary/overloaded_autoderef_xc.rs b/src/test/auxiliary/overloaded_autoderef_xc.rs index caa9bbe5736e4..3c8cba13ae73d 100644 --- a/src/test/auxiliary/overloaded_autoderef_xc.rs +++ b/src/test/auxiliary/overloaded_autoderef_xc.rs @@ -11,7 +11,8 @@ use std::ops::Deref; struct DerefWithHelper { - pub helper: H + pub helper: H, + pub value: Option } trait Helper { @@ -34,6 +35,6 @@ impl> Deref for DerefWithHelper { // Test cross-crate autoderef + vtable. pub fn check(x: T, y: T) -> bool { - let d: DerefWithHelper, T> = DerefWithHelper { helper: Some(x) }; + let d: DerefWithHelper, T> = DerefWithHelper { helper: Some(x), value: None }; d.eq(&y) } diff --git a/src/test/auxiliary/private_trait_xc.rs b/src/test/auxiliary/private_trait_xc.rs index 37ee10c8d3733..42691579491bb 100644 --- a/src/test/auxiliary/private_trait_xc.rs +++ b/src/test/auxiliary/private_trait_xc.rs @@ -8,4 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo {} +trait Foo : ::std::marker::MarkerTrait {} diff --git a/src/test/auxiliary/svh-a-base.rs b/src/test/auxiliary/svh-a-base.rs index 12833daf60458..04f1062c16f02 100644 --- a/src/test/auxiliary/svh-a-base.rs +++ b/src/test/auxiliary/svh-a-base.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-change-lit.rs b/src/test/auxiliary/svh-a-change-lit.rs index 9e74bf281358f..fabd2289e9a44 100644 --- a/src/test/auxiliary/svh-a-change-lit.rs +++ b/src/test/auxiliary/svh-a-change-lit.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-change-significant-cfg.rs b/src/test/auxiliary/svh-a-change-significant-cfg.rs index c900550041b5c..3fdb861bd40c1 100644 --- a/src/test/auxiliary/svh-a-change-significant-cfg.rs +++ b/src/test/auxiliary/svh-a-change-significant-cfg.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-change-trait-bound.rs b/src/test/auxiliary/svh-a-change-trait-bound.rs index 04f8eb3cf9bc0..3116d24673d48 100644 --- a/src/test/auxiliary/svh-a-change-trait-bound.rs +++ b/src/test/auxiliary/svh-a-change-trait-bound.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-change-type-arg.rs b/src/test/auxiliary/svh-a-change-type-arg.rs index c7e0a18768a3d..b49a1533628f6 100644 --- a/src/test/auxiliary/svh-a-change-type-arg.rs +++ b/src/test/auxiliary/svh-a-change-type-arg.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-change-type-ret.rs b/src/test/auxiliary/svh-a-change-type-ret.rs index 5100af323183b..6562a93135f39 100644 --- a/src/test/auxiliary/svh-a-change-type-ret.rs +++ b/src/test/auxiliary/svh-a-change-type-ret.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-change-type-static.rs b/src/test/auxiliary/svh-a-change-type-static.rs index 077c33cb90d75..c7b392c6ee82b 100644 --- a/src/test/auxiliary/svh-a-change-type-static.rs +++ b/src/test/auxiliary/svh-a-change-type-static.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-comment.rs b/src/test/auxiliary/svh-a-comment.rs index d481fa5a1fa3b..450f61020260d 100644 --- a/src/test/auxiliary/svh-a-comment.rs +++ b/src/test/auxiliary/svh-a-comment.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-doc.rs b/src/test/auxiliary/svh-a-doc.rs index 9e99a355ac1ee..c000737c854c6 100644 --- a/src/test/auxiliary/svh-a-doc.rs +++ b/src/test/auxiliary/svh-a-doc.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-macro.rs b/src/test/auxiliary/svh-a-macro.rs index b8dd497ac99c8..1e12659dc4b92 100644 --- a/src/test/auxiliary/svh-a-macro.rs +++ b/src/test/auxiliary/svh-a-macro.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-no-change.rs b/src/test/auxiliary/svh-a-no-change.rs index 12833daf60458..04f1062c16f02 100644 --- a/src/test/auxiliary/svh-a-no-change.rs +++ b/src/test/auxiliary/svh-a-no-change.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-redundant-cfg.rs b/src/test/auxiliary/svh-a-redundant-cfg.rs index 690ddc670f5fa..1e82b74f1ef2e 100644 --- a/src/test/auxiliary/svh-a-redundant-cfg.rs +++ b/src/test/auxiliary/svh-a-redundant-cfg.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/svh-a-whitespace.rs b/src/test/auxiliary/svh-a-whitespace.rs index 216e8e997f22d..3c3dac9cdab96 100644 --- a/src/test/auxiliary/svh-a-whitespace.rs +++ b/src/test/auxiliary/svh-a-whitespace.rs @@ -15,12 +15,14 @@ #![crate_name = "a"] +use std::marker::MarkerTrait; + macro_rules! three { () => { 3 } } -pub trait U {} -pub trait V {} +pub trait U : MarkerTrait {} +pub trait V : MarkerTrait {} impl U for () {} impl V for () {} diff --git a/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs b/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs index 1695e474de999..a7c469fccaa5a 100644 --- a/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs +++ b/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait Trait {} +pub trait Trait { + fn dummy(&self) { } +} pub struct Foo { pub x: T, diff --git a/src/test/auxiliary/trait_impl_conflict.rs b/src/test/auxiliary/trait_impl_conflict.rs index 990bc21604959..0982efbdbf47e 100644 --- a/src/test/auxiliary/trait_impl_conflict.rs +++ b/src/test/auxiliary/trait_impl_conflict.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait Foo { +pub trait Foo : ::std::marker::MarkerTrait { } impl Foo for int { diff --git a/src/test/auxiliary/use_from_trait_xc.rs b/src/test/auxiliary/use_from_trait_xc.rs index 22e0d3168cadc..56fb40bc0a469 100644 --- a/src/test/auxiliary/use_from_trait_xc.rs +++ b/src/test/auxiliary/use_from_trait_xc.rs @@ -11,7 +11,7 @@ pub use self::sub::{Bar, Baz}; pub trait Trait { - fn foo(); + fn foo(&self); } struct Foo; diff --git a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs index 621f5ec9660fc..edd1b8255ccdc 100644 --- a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs +++ b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs @@ -16,8 +16,12 @@ #![feature(no_std)] #![no_std] +#[lang="phantom_fn"] +pub trait PhantomFn { } +impl PhantomFn for U { } + #[lang="sized"] -pub trait Sized { +pub trait Sized : PhantomFn { // Empty. } diff --git a/src/test/compile-fail/associated-types-coherence-failure.rs b/src/test/compile-fail/associated-types-coherence-failure.rs index 95a68dd669836..b7a16c68a34e1 100644 --- a/src/test/compile-fail/associated-types-coherence-failure.rs +++ b/src/test/compile-fail/associated-types-coherence-failure.rs @@ -11,9 +11,10 @@ // Test that coherence detects overlap when some of the types in the // impls are projections of associated type. Issue #20624. +use std::marker::PhantomData; use std::ops::Deref; -pub struct Cow<'a, B: ?Sized>; +pub struct Cow<'a, B: ?Sized>(PhantomData<(&'a (),B)>); /// Trait for moving into a `Cow` pub trait IntoCow<'a, B: ?Sized> { diff --git a/src/test/compile-fail/associated-types-eq-expr-path.rs b/src/test/compile-fail/associated-types-eq-expr-path.rs index 9baa7f1ad5a69..c48f9972ebc18 100644 --- a/src/test/compile-fail/associated-types-eq-expr-path.rs +++ b/src/test/compile-fail/associated-types-eq-expr-path.rs @@ -10,7 +10,7 @@ // Check that an associated type cannot be bound in an expression path. -trait Foo { +trait Foo : ::std::marker::MarkerTrait { type A; fn bar() -> isize; } diff --git a/src/test/compile-fail/associated-types-issue-17359.rs b/src/test/compile-fail/associated-types-issue-17359.rs index fa09ae793bf63..625f4cdb8ef3d 100644 --- a/src/test/compile-fail/associated-types-issue-17359.rs +++ b/src/test/compile-fail/associated-types-issue-17359.rs @@ -11,7 +11,7 @@ // Test that we do not ICE when an impl is missing an associated type (and that we report // a useful error, of course). -trait Trait { +trait Trait : ::std::marker::MarkerTrait { type Type; } diff --git a/src/test/compile-fail/associated-types-multiple-types-one-trait.rs b/src/test/compile-fail/associated-types-multiple-types-one-trait.rs index 9436f825de89d..5632f148da67c 100644 --- a/src/test/compile-fail/associated-types-multiple-types-one-trait.rs +++ b/src/test/compile-fail/associated-types-multiple-types-one-trait.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo { +trait Foo : ::std::marker::MarkerTrait { type X; type Y; } diff --git a/src/test/compile-fail/associated-types-no-suitable-supertrait.rs b/src/test/compile-fail/associated-types-no-suitable-supertrait.rs index a3f2850b29464..2b84c38f80b54 100644 --- a/src/test/compile-fail/associated-types-no-suitable-supertrait.rs +++ b/src/test/compile-fail/associated-types-no-suitable-supertrait.rs @@ -11,7 +11,7 @@ // Check that we get an error when you use `::Value` in // the trait definition but `Self` does not, in fact, implement `Get`. -trait Get { +trait Get : ::std::marker::MarkerTrait { type Value; } diff --git a/src/test/compile-fail/associated-types-path-2.rs b/src/test/compile-fail/associated-types-path-2.rs index 51a37b517ddeb..b9a62ff4e417a 100644 --- a/src/test/compile-fail/associated-types-path-2.rs +++ b/src/test/compile-fail/associated-types-path-2.rs @@ -12,6 +12,8 @@ pub trait Foo { type A; + + fn dummy(&self) { } } impl Foo for i32 { diff --git a/src/test/compile-fail/associated-types-unconstrained.rs b/src/test/compile-fail/associated-types-unconstrained.rs index aecbf217a5b25..8832028f9aba1 100644 --- a/src/test/compile-fail/associated-types-unconstrained.rs +++ b/src/test/compile-fail/associated-types-unconstrained.rs @@ -10,7 +10,7 @@ // Check that an associated type cannot be bound in an expression path. -trait Foo { +trait Foo : ::std::marker::MarkerTrait { type A; fn bar() -> isize; } diff --git a/src/test/compile-fail/bad-mid-path-type-params.rs b/src/test/compile-fail/bad-mid-path-type-params.rs index c91849ca53e1a..3e02a11c378bd 100644 --- a/src/test/compile-fail/bad-mid-path-type-params.rs +++ b/src/test/compile-fail/bad-mid-path-type-params.rs @@ -10,13 +10,6 @@ // ignore-tidy-linelength -#![feature(no_std)] -#![no_std] -#![feature(lang_items)] - -#[lang="sized"] -pub trait Sized {} - struct S { contents: T, } diff --git a/src/test/compile-fail/bad-sized.rs b/src/test/compile-fail/bad-sized.rs index 69be6414e4c90..1944acbe1f345 100644 --- a/src/test/compile-fail/bad-sized.rs +++ b/src/test/compile-fail/bad-sized.rs @@ -12,7 +12,7 @@ use std::cell::RefCell; -trait Trait {} +trait Trait : ::std::marker::MarkerTrait {} pub fn main() { let x: Vec = Vec::new(); diff --git a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs index 27d97d18c949f..d4decb713498d 100644 --- a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs +++ b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs @@ -10,6 +10,7 @@ use std::fmt::Show; use std::default::Default; +use std::marker::MarkerTrait; // Test that two blanket impls conflict (at least without negative // bounds). After all, some other crate could implement Even or Odd @@ -19,9 +20,9 @@ trait MyTrait { fn get(&self) -> usize; } -trait Even { } +trait Even : MarkerTrait { } -trait Odd { } +trait Odd : MarkerTrait { } impl Even for isize { } diff --git a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs index 0f233b78c7216..b1ee1762b6e71 100644 --- a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs +++ b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs @@ -19,9 +19,9 @@ trait MyTrait { fn get(&self) -> usize; } -trait Even { } +trait Even : ::std::marker::MarkerTrait { } -trait Odd { } +trait Odd : ::std::marker::MarkerTrait { } impl MyTrait for T { //~ ERROR E0119 fn get(&self) -> usize { 0 } diff --git a/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs b/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs index c9dfb8201a98a..a225f6cf47304 100644 --- a/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs +++ b/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs @@ -10,18 +10,18 @@ #![feature(optin_builtin_traits)] -trait MyTrait {} +trait MyTrait : ::std::marker::MarkerTrait {} -struct TestType; +struct TestType(::std::marker::PhantomData); -unsafe impl Send for TestType {} +unsafe impl Send for TestType {} //~^ ERROR conflicting implementations for trait `core::marker::Send` //~^^ ERROR conflicting implementations for trait `core::marker::Send` impl !Send for TestType {} //~^ ERROR conflicting implementations for trait `core::marker::Send` -unsafe impl Send for TestType {} +unsafe impl Send for TestType {} //~^ ERROR error: conflicting implementations for trait `core::marker::Send` impl !Send for TestType {} diff --git a/src/test/compile-fail/cross-borrow-trait.rs b/src/test/compile-fail/cross-borrow-trait.rs index 86b7a8c89184a..c97a9950d78d0 100644 --- a/src/test/compile-fail/cross-borrow-trait.rs +++ b/src/test/compile-fail/cross-borrow-trait.rs @@ -14,7 +14,7 @@ #![feature(box_syntax)] struct Foo; -trait Trait {} +trait Trait : ::std::marker::MarkerTrait {} impl Trait for Foo {} pub fn main() { diff --git a/src/test/compile-fail/destructure-trait-ref.rs b/src/test/compile-fail/destructure-trait-ref.rs index f2e068cc4ff1b..d8b3f297a1123 100644 --- a/src/test/compile-fail/destructure-trait-ref.rs +++ b/src/test/compile-fail/destructure-trait-ref.rs @@ -14,7 +14,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] -trait T {} +trait T : ::std::marker::MarkerTrait {} impl T for isize {} fn main() { diff --git a/src/test/compile-fail/dst-bad-coerce1.rs b/src/test/compile-fail/dst-bad-coerce1.rs index 2b96c5ebe1284..6d9ba8d44c089 100644 --- a/src/test/compile-fail/dst-bad-coerce1.rs +++ b/src/test/compile-fail/dst-bad-coerce1.rs @@ -15,7 +15,7 @@ struct Fat { } struct Foo; -trait Bar {} +trait Bar : ::std::marker::MarkerTrait {} pub fn main() { // With a vec of isize. diff --git a/src/test/compile-fail/dst-bad-coerce2.rs b/src/test/compile-fail/dst-bad-coerce2.rs index 160197368d6d9..aa687266acb8f 100644 --- a/src/test/compile-fail/dst-bad-coerce2.rs +++ b/src/test/compile-fail/dst-bad-coerce2.rs @@ -15,7 +15,7 @@ struct Fat { } struct Foo; -trait Bar {} +trait Bar : ::std::marker::MarkerTrait {} impl Bar for Foo {} pub fn main() { diff --git a/src/test/compile-fail/dst-bad-coerce3.rs b/src/test/compile-fail/dst-bad-coerce3.rs index 347a2d2ecbe68..46b89e1122a2c 100644 --- a/src/test/compile-fail/dst-bad-coerce3.rs +++ b/src/test/compile-fail/dst-bad-coerce3.rs @@ -15,7 +15,7 @@ struct Fat { } struct Foo; -trait Bar {} +trait Bar : ::std::marker::MarkerTrait {} impl Bar for Foo {} fn baz<'a>() { diff --git a/src/test/compile-fail/dst-bad-coercions.rs b/src/test/compile-fail/dst-bad-coercions.rs index b30eada162b84..8ec1034bc4d28 100644 --- a/src/test/compile-fail/dst-bad-coercions.rs +++ b/src/test/compile-fail/dst-bad-coercions.rs @@ -10,8 +10,10 @@ // Test implicit coercions involving DSTs and raw pointers. +use std::marker::MarkerTrait; + struct S; -trait T {} +trait T : MarkerTrait {} impl T for S {} struct Foo { diff --git a/src/test/compile-fail/dst-object-from-unsized-type.rs b/src/test/compile-fail/dst-object-from-unsized-type.rs index 87ff4291f50e2..a1f0dda671e7d 100644 --- a/src/test/compile-fail/dst-object-from-unsized-type.rs +++ b/src/test/compile-fail/dst-object-from-unsized-type.rs @@ -10,7 +10,7 @@ // Test that we cannot create objects from unsized types. -trait Foo {} +trait Foo : ::std::marker::MarkerTrait {} impl Foo for str {} fn test1(t: &T) { diff --git a/src/test/compile-fail/exclusive-drop-and-copy.rs b/src/test/compile-fail/exclusive-drop-and-copy.rs index 17453bc677f2b..f47f14d587992 100644 --- a/src/test/compile-fail/exclusive-drop-and-copy.rs +++ b/src/test/compile-fail/exclusive-drop-and-copy.rs @@ -20,7 +20,7 @@ impl Drop for Foo { } #[derive(Copy)] //~ ERROR the trait `Copy` may not be implemented -struct Bar; +struct Bar(::std::marker::PhantomData); #[unsafe_destructor] impl Drop for Bar { diff --git a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs index 02f09749d614d..9fea5e609d1f4 100644 --- a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs +++ b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs @@ -8,10 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Foo; +use std::marker; + +struct Foo( + marker::PhantomData<(A,B,C)>); impl Foo { - fn new() -> Foo {Foo} + fn new() -> Foo {Foo(marker::PhantomData)} } fn main() { diff --git a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs index d88da2625c187..73c19aa012dcf 100644 --- a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs +++ b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs @@ -8,12 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + struct Heap; -struct Vec; +struct Vec( + marker::PhantomData<(T,A)>); impl Vec { - fn new() -> Vec {Vec} + fn new() -> Vec {Vec(marker::PhantomData)} } fn main() { diff --git a/src/test/compile-fail/generic-lifetime-trait-impl.rs b/src/test/compile-fail/generic-lifetime-trait-impl.rs index fc54002820e01..9b9f09f477757 100644 --- a/src/test/compile-fail/generic-lifetime-trait-impl.rs +++ b/src/test/compile-fail/generic-lifetime-trait-impl.rs @@ -16,9 +16,12 @@ // // Regression test for issue #16218. -trait Bar<'a> {} +trait Bar<'a> { + fn dummy(&'a self); +} trait Foo<'a> { + fn dummy(&'a self) { } fn bar<'b, T: Bar<'b>>(self) -> &'b str; } diff --git a/src/test/compile-fail/generic-type-less-params-with-defaults.rs b/src/test/compile-fail/generic-type-less-params-with-defaults.rs index f25d8f99b8d54..37737fda4749e 100644 --- a/src/test/compile-fail/generic-type-less-params-with-defaults.rs +++ b/src/test/compile-fail/generic-type-less-params-with-defaults.rs @@ -8,9 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + struct Heap; -struct Vec; +struct Vec( + marker::PhantomData<(T,A)>); fn main() { let _: Vec; //~ ERROR wrong number of type arguments: expected at least 1, found 0 diff --git a/src/test/compile-fail/generic-type-more-params-with-defaults.rs b/src/test/compile-fail/generic-type-more-params-with-defaults.rs index 19d303488acb0..ad7e4f190c5b9 100644 --- a/src/test/compile-fail/generic-type-more-params-with-defaults.rs +++ b/src/test/compile-fail/generic-type-more-params-with-defaults.rs @@ -8,9 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + struct Heap; -struct Vec; +struct Vec( + marker::PhantomData<(T,A)>); fn main() { let _: Vec; diff --git a/src/test/compile-fail/generic-type-params-name-repr.rs b/src/test/compile-fail/generic-type-params-name-repr.rs index 3e34344d78b9d..a452cd35f943f 100644 --- a/src/test/compile-fail/generic-type-params-name-repr.rs +++ b/src/test/compile-fail/generic-type-params-name-repr.rs @@ -8,13 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + struct A; struct B; struct C; -struct Foo; +struct Foo(marker::PhantomData<(T,U,V)>); -struct Hash; -struct HashMap>; +struct Hash(marker::PhantomData); +struct HashMap>(marker::PhantomData<(K,V,H)>); fn main() { // Ensure that the printed type doesn't include the default type params... diff --git a/src/test/compile-fail/issue-11515.rs b/src/test/compile-fail/issue-11515.rs index f0089b0ae5b34..4ff574e939df6 100644 --- a/src/test/compile-fail/issue-11515.rs +++ b/src/test/compile-fail/issue-11515.rs @@ -10,7 +10,7 @@ #![feature(box_syntax)] -struct Test<'s> { +struct Test { func: Box } diff --git a/src/test/compile-fail/issue-13853-2.rs b/src/test/compile-fail/issue-13853-2.rs index ea0d880f4a1cc..dc697e4784f85 100644 --- a/src/test/compile-fail/issue-13853-2.rs +++ b/src/test/compile-fail/issue-13853-2.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait FromStructReader<'a> { } +use std::marker::PhantomFn; + +trait FromStructReader<'a> : PhantomFn<(Self,&'a ())> { } trait ResponseHook { fn get<'a, T: FromStructReader<'a>>(&'a self); } diff --git a/src/test/compile-fail/issue-13853-3.rs b/src/test/compile-fail/issue-13853-3.rs index f10c47b594ea2..7ca158c3e3204 100644 --- a/src/test/compile-fail/issue-13853-3.rs +++ b/src/test/compile-fail/issue-13853-3.rs @@ -10,6 +10,8 @@ #![crate_type = "lib"] +use std::marker::PhantomData; + enum NodeContents<'a> { Children(Vec>), } @@ -22,11 +24,12 @@ impl<'a> Drop for NodeContents<'a> { struct Node<'a> { contents: NodeContents<'a>, + marker: PhantomData<&'a ()>, } impl<'a> Node<'a> { fn noName(contents: NodeContents<'a>) -> Node<'a> { - Node{ contents: contents,} + Node { contents: contents, marker: PhantomData } } } diff --git a/src/test/compile-fail/issue-13853.rs b/src/test/compile-fail/issue-13853.rs index 251da2c6b3ee9..cd3f337c4ab65 100644 --- a/src/test/compile-fail/issue-13853.rs +++ b/src/test/compile-fail/issue-13853.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Node { +use std::marker::MarkerTrait; + +trait Node : MarkerTrait { fn zomg(); } diff --git a/src/test/compile-fail/issue-14285.rs b/src/test/compile-fail/issue-14285.rs index cbf4412a81df2..3a5df9e805bdb 100644 --- a/src/test/compile-fail/issue-14285.rs +++ b/src/test/compile-fail/issue-14285.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo {} +trait Foo { + fn dummy(&self) { } +} struct A; diff --git a/src/test/compile-fail/issue-14853.rs b/src/test/compile-fail/issue-14853.rs index 51deb99a4f2cd..0b846651acf46 100644 --- a/src/test/compile-fail/issue-14853.rs +++ b/src/test/compile-fail/issue-14853.rs @@ -9,8 +9,9 @@ // except according to those terms. use std::fmt::Debug; +use std::marker::MarkerTrait; -trait Str {} +trait Str : MarkerTrait {} trait Something { fn yay(_: Option, thing: &[T]); diff --git a/src/test/compile-fail/issue-16747.rs b/src/test/compile-fail/issue-16747.rs index 814b885e3aafc..a213234b89b0f 100644 --- a/src/test/compile-fail/issue-16747.rs +++ b/src/test/compile-fail/issue-16747.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait ListItem<'a> { +use std::marker::MarkerTrait; + +trait ListItem<'a> : MarkerTrait { fn list_name() -> &'a str; } diff --git a/src/test/compile-fail/issue-17431-4.rs b/src/test/compile-fail/issue-17431-4.rs index 1e27f02556470..22aaa796ad0f4 100644 --- a/src/test/compile-fail/issue-17431-4.rs +++ b/src/test/compile-fail/issue-17431-4.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Foo { foo: Option>> } +use std::marker; + +struct Foo { foo: Option>>, marker: marker::PhantomData } //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable impl Foo { fn bar(&self) {} } diff --git a/src/test/compile-fail/issue-17431-5.rs b/src/test/compile-fail/issue-17431-5.rs index d22d79ecaa550..cc9cc2e3c035c 100644 --- a/src/test/compile-fail/issue-17431-5.rs +++ b/src/test/compile-fail/issue-17431-5.rs @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + struct Foo { foo: Bar } -struct Bar { x: Bar } +struct Bar { x: Bar , marker: marker::PhantomData } //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable impl Foo { fn foo(&self) {} } diff --git a/src/test/compile-fail/issue-17551.rs b/src/test/compile-fail/issue-17551.rs index e037ba92b4a6a..5781cb7411743 100644 --- a/src/test/compile-fail/issue-17551.rs +++ b/src/test/compile-fail/issue-17551.rs @@ -10,9 +10,11 @@ #![feature(unboxed_closures)] -struct B; +use std::marker; + +struct B(marker::PhantomData); fn main() { - let foo = B; //~ ERROR: unable to infer enough type information + let foo = B(marker::PhantomData); //~ ERROR unable to infer enough type information let closure = || foo; } diff --git a/src/test/compile-fail/issue-18107.rs b/src/test/compile-fail/issue-18107.rs index 83427e8aa67f9..bdb5af0b82489 100644 --- a/src/test/compile-fail/issue-18107.rs +++ b/src/test/compile-fail/issue-18107.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker::MarkerTrait; - -pub trait AbstractRenderer {} +pub trait AbstractRenderer : MarkerTrait {} fn _create_render(_: &()) -> AbstractRenderer diff --git a/src/test/compile-fail/issue-18611.rs b/src/test/compile-fail/issue-18611.rs index a662e9ca98ee8..e81a576fa63d5 100644 --- a/src/test/compile-fail/issue-18611.rs +++ b/src/test/compile-fail/issue-18611.rs @@ -8,11 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker::MarkerTrait; + fn add_state(op: ::State) { //~^ ERROR the trait `HasState` is not implemented for the type `isize` } -trait HasState { +trait HasState : MarkerTrait { type State; } diff --git a/src/test/compile-fail/issue-18783.rs b/src/test/compile-fail/issue-18783.rs index d26bf68cb5dfe..1bbbdf79d28b7 100644 --- a/src/test/compile-fail/issue-18783.rs +++ b/src/test/compile-fail/issue-18783.rs @@ -26,6 +26,7 @@ fn ufcs() { Push::push(&c, box || y = 0); Push::push(&c, box || y = 0); +//~^ ERROR cannot borrow `y` as mutable more than once at a time } trait Push<'c> { diff --git a/src/test/compile-fail/issue-18819.rs b/src/test/compile-fail/issue-18819.rs index 3a9de74104364..951d78410b814 100644 --- a/src/test/compile-fail/issue-18819.rs +++ b/src/test/compile-fail/issue-18819.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo { +use std::marker::MarkerTrait; + +trait Foo : MarkerTrait { type Item; } diff --git a/src/test/compile-fail/issue-19660.rs b/src/test/compile-fail/issue-19660.rs index 14601e67a77c1..77aba7335bdf9 100644 --- a/src/test/compile-fail/issue-19660.rs +++ b/src/test/compile-fail/issue-19660.rs @@ -13,8 +13,12 @@ #![feature(lang_items, start, no_std)] #![no_std] +#[lang="phantom_fn"] +trait PhantomFn { } +impl PhantomFn for U { } + #[lang = "sized"] -trait Sized {} +trait Sized : PhantomFn {} #[start] fn main(_: int, _: *const *const u8) -> int { diff --git a/src/test/compile-fail/issue-2063.rs b/src/test/compile-fail/issue-2063.rs index 00607f850347c..aed395d17ea9c 100644 --- a/src/test/compile-fail/issue-2063.rs +++ b/src/test/compile-fail/issue-2063.rs @@ -12,10 +12,11 @@ // cause compiler to loop. Note that no instances // of such a type could ever be constructed. +use std::marker::MarkerTrait; struct t(Box); //~ ERROR this type cannot be instantiated -trait to_str_2 { +trait to_str_2 : MarkerTrait { fn my_to_string() -> String; } diff --git a/src/test/compile-fail/issue-20831-debruijn.rs b/src/test/compile-fail/issue-20831-debruijn.rs index aaf45f2739891..5b623ac377b21 100644 --- a/src/test/compile-fail/issue-20831-debruijn.rs +++ b/src/test/compile-fail/issue-20831-debruijn.rs @@ -13,10 +13,11 @@ // below. Note that changing to a named lifetime made the problem go // away. -use std::ops::{Shl, Shr}; use std::cell::RefCell; +use std::marker::MarkerTrait; +use std::ops::{Shl, Shr}; -pub trait Subscriber { +pub trait Subscriber : MarkerTrait { type Input; } diff --git a/src/test/compile-fail/issue-2611-4.rs b/src/test/compile-fail/issue-2611-4.rs index 31796e5e20c44..24cc0099b89a5 100644 --- a/src/test/compile-fail/issue-2611-4.rs +++ b/src/test/compile-fail/issue-2611-4.rs @@ -12,7 +12,7 @@ // than the trait method it's implementing trait A { - fn b(x: C) -> C; + fn b(&self, x: C) -> C; } struct E { @@ -20,7 +20,7 @@ struct E { } impl A for E { - fn b(_x: F) -> F { panic!() } + fn b(&self, _x: F) -> F { panic!() } //~^ ERROR `F : core::marker::Sync` appears on the impl method } diff --git a/src/test/compile-fail/issue-3008-3.rs b/src/test/compile-fail/issue-3008-3.rs index a338a01690dea..af6cee1f10749 100644 --- a/src/test/compile-fail/issue-3008-3.rs +++ b/src/test/compile-fail/issue-3008-3.rs @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + enum E1 { V1(E2), } -enum E2 { V2(E2), } +enum E2 { V2(E2, marker::PhantomData), } //~^ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable impl E1 { fn foo(&self) {} } diff --git a/src/test/compile-fail/issue-4972.rs b/src/test/compile-fail/issue-4972.rs index 9a398796d2abf..f384dba7c9e3d 100644 --- a/src/test/compile-fail/issue-4972.rs +++ b/src/test/compile-fail/issue-4972.rs @@ -11,7 +11,9 @@ #![feature(box_patterns)] #![feature(box_syntax)] -trait MyTrait { } +trait MyTrait { + fn dummy(&self) {} +} pub enum TraitWrapper { A(Box), diff --git a/src/test/compile-fail/issue-5035-2.rs b/src/test/compile-fail/issue-5035-2.rs index 9e324cdd61eb0..d316b44794ad6 100644 --- a/src/test/compile-fail/issue-5035-2.rs +++ b/src/test/compile-fail/issue-5035-2.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait I {} +use std::marker::MarkerTrait; + +trait I : MarkerTrait {} type K = I+'static; fn foo(_x: K) {} //~ ERROR: the trait `core::marker::Sized` is not implemented diff --git a/src/test/compile-fail/issue-5543.rs b/src/test/compile-fail/issue-5543.rs index cf98f1572e560..eccbc7896605e 100644 --- a/src/test/compile-fail/issue-5543.rs +++ b/src/test/compile-fail/issue-5543.rs @@ -10,7 +10,9 @@ #![feature(box_syntax)] -trait Foo {} +use std::marker::MarkerTrait; + +trait Foo : MarkerTrait {} impl Foo for u8 {} fn main() { diff --git a/src/test/compile-fail/issue-5883.rs b/src/test/compile-fail/issue-5883.rs index 9ff957b6e6dea..b0db990619535 100644 --- a/src/test/compile-fail/issue-5883.rs +++ b/src/test/compile-fail/issue-5883.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait A {} +use std::marker::MarkerTrait; + +trait A : MarkerTrait {} struct Struct { r: A+'static @@ -20,6 +22,6 @@ fn new_struct(r: A+'static) Struct { r: r } } -trait Curve {} +trait Curve : MarkerTrait {} enum E {X(Curve+'static)} fn main() {} diff --git a/src/test/compile-fail/issue-6458.rs b/src/test/compile-fail/issue-6458.rs index efa3100360b5c..0bf9a3c2d4867 100644 --- a/src/test/compile-fail/issue-6458.rs +++ b/src/test/compile-fail/issue-6458.rs @@ -8,13 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub struct TypeWithState; +use std::marker; + +pub struct TypeWithState(marker::PhantomData); pub struct MyState; pub fn foo(_: TypeWithState) {} pub fn bar() { - foo(TypeWithState); //~ ERROR type annotations required + foo(TypeWithState(marker::PhantomData)); //~ ERROR type annotations required } fn main() { diff --git a/src/test/compile-fail/issue-7575.rs b/src/test/compile-fail/issue-7575.rs index 49e54f25bf64b..7d65870e2dbca 100644 --- a/src/test/compile-fail/issue-7575.rs +++ b/src/test/compile-fail/issue-7575.rs @@ -10,12 +10,14 @@ // Test the mechanism for warning about possible missing `self` declarations. +use std::marker::MarkerTrait; + trait CtxtFn { fn f8(self, usize) -> usize; fn f9(usize) -> usize; //~ NOTE candidate } -trait OtherTrait { +trait OtherTrait : MarkerTrait { fn f9(usize) -> usize; //~ NOTE candidate } @@ -24,7 +26,7 @@ trait OtherTrait { // declaration to match against, so we wind up prisizeing it as a // candidate. This seems not unreasonable -- perhaps the user meant to // implement it, after all. -trait UnusedTrait { +trait UnusedTrait : MarkerTrait { fn f9(usize) -> usize; //~ NOTE candidate } @@ -52,7 +54,7 @@ impl Myisize { } } -trait ManyImplTrait { +trait ManyImplTrait : MarkerTrait { fn is_str() -> bool { //~ NOTE candidate false } diff --git a/src/test/compile-fail/issue-8727.rs b/src/test/compile-fail/issue-8727.rs index d1a86d334cb44..72da6dcaa6c45 100644 --- a/src/test/compile-fail/issue-8727.rs +++ b/src/test/compile-fail/issue-8727.rs @@ -13,16 +13,12 @@ // Verify the compiler fails with an error on infinite function // recursions. -struct Data(Box>); - -fn generic( _ : Vec<(Data,T)> ) { - let rec : Vec<(Data,(bool,T))> = Vec::new(); - generic( rec ); +fn generic() { + generic::>(); } fn main () { // Use generic at least once to trigger instantiation. - let input : Vec<(Data,())> = Vec::new(); - generic(input); + generic::(); } diff --git a/src/test/compile-fail/kindck-copy.rs b/src/test/compile-fail/kindck-copy.rs index 56f83d9300861..74e372e41eb0a 100644 --- a/src/test/compile-fail/kindck-copy.rs +++ b/src/test/compile-fail/kindck-copy.rs @@ -10,12 +10,12 @@ // Test which of the builtin types are considered POD. - +use std::marker::MarkerTrait; use std::rc::Rc; fn assert_copy() { } -trait Dummy { } +trait Dummy : MarkerTrait { } #[derive(Copy)] struct MyStruct { diff --git a/src/test/compile-fail/kindck-impl-type-params-2.rs b/src/test/compile-fail/kindck-impl-type-params-2.rs index 2731be7308a4a..b575144f637f1 100644 --- a/src/test/compile-fail/kindck-impl-type-params-2.rs +++ b/src/test/compile-fail/kindck-impl-type-params-2.rs @@ -10,7 +10,9 @@ #![feature(box_syntax)] -trait Foo { +use std::marker::MarkerTrait; + +trait Foo : MarkerTrait { } impl Foo for T { diff --git a/src/test/compile-fail/kindck-impl-type-params.rs b/src/test/compile-fail/kindck-impl-type-params.rs index d5276efa8be98..dffc8fa2abd70 100644 --- a/src/test/compile-fail/kindck-impl-type-params.rs +++ b/src/test/compile-fail/kindck-impl-type-params.rs @@ -13,40 +13,44 @@ #![feature(box_syntax)] -struct S; +use std::marker; -trait Gettable {} +struct S(marker::PhantomData); + +trait Gettable { + fn get(&self) -> T { panic!() } +} impl Gettable for S {} fn f(val: T) { - let t: S = S; + let t: S = S(marker::PhantomData); let a = &t as &Gettable; //~^ ERROR the trait `core::marker::Send` is not implemented //~^^ ERROR the trait `core::marker::Copy` is not implemented } fn g(val: T) { - let t: S = S; + let t: S = S(marker::PhantomData); let a: &Gettable = &t; //~^ ERROR the trait `core::marker::Send` is not implemented //~^^ ERROR the trait `core::marker::Copy` is not implemented } fn foo<'a>() { - let t: S<&'a isize> = S; + let t: S<&'a isize> = S(marker::PhantomData); let a = &t as &Gettable<&'a isize>; - //~^ ERROR the type `&'a isize` does not fulfill the required lifetime + //~^ ERROR cannot infer } fn foo2<'a>() { - let t: Box> = box S; + let t: Box> = box S(marker::PhantomData); let a = t as Box>; //~^ ERROR the trait `core::marker::Copy` is not implemented } fn foo3<'a>() { - let t: Box> = box S; + let t: Box> = box S(marker::PhantomData); let a: Box> = t; //~^ ERROR the trait `core::marker::Copy` is not implemented } diff --git a/src/test/compile-fail/kindck-send-object.rs b/src/test/compile-fail/kindck-send-object.rs index 570f7ad7fe3bf..0c68401bb2b95 100644 --- a/src/test/compile-fail/kindck-send-object.rs +++ b/src/test/compile-fail/kindck-send-object.rs @@ -12,8 +12,10 @@ // in this file all test the "kind" violates detected during kindck. // See all `regions-bounded-by-send.rs` +use std::marker::MarkerTrait; + fn assert_send() { } -trait Dummy { } +trait Dummy : MarkerTrait { } trait Message : Send { } // careful with object types, who knows what they close over... diff --git a/src/test/compile-fail/kindck-send-object1.rs b/src/test/compile-fail/kindck-send-object1.rs index 48d5215b7085b..f86eac8b16bd2 100644 --- a/src/test/compile-fail/kindck-send-object1.rs +++ b/src/test/compile-fail/kindck-send-object1.rs @@ -12,8 +12,10 @@ // is broken into two parts because some errors occur in distinct // phases in the compiler. See kindck-send-object2.rs as well! +use std::marker::MarkerTrait; + fn assert_send() { } -trait Dummy { } +trait Dummy : MarkerTrait { } // careful with object types, who knows what they close over... fn test51<'a>() { diff --git a/src/test/compile-fail/kindck-send-object2.rs b/src/test/compile-fail/kindck-send-object2.rs index d3d166e2a6916..08516e67318ce 100644 --- a/src/test/compile-fail/kindck-send-object2.rs +++ b/src/test/compile-fail/kindck-send-object2.rs @@ -10,8 +10,10 @@ // Continue kindck-send-object1.rs. +use std::marker::MarkerTrait; + fn assert_send() { } -trait Dummy { } +trait Dummy : MarkerTrait { } fn test50() { assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Sync` is not implemented diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs index 04c5b223cb875..66d8927ee51b7 100644 --- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs +++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs @@ -10,7 +10,9 @@ // ignore-tidy-linelength -struct Bar<'x, 'y, 'z> { bar: &'y i32, baz: i32 } +use std::marker::PhantomData; + +struct Bar<'x, 'y, 'z> { bar: &'y i32, baz: i32, marker: PhantomData<(&'x(),&'y(),&'z())> } fn bar1<'a>(x: &Bar) -> (&'a i32, &'a i32, &'a i32) { //~^ HELP: consider using an explicit lifetime parameter as shown: fn bar1<'b, 'c, 'a>(x: &'a Bar<'b, 'a, 'c>) -> (&'a i32, &'a i32, &'a i32) (x.bar, &x.baz, &x.baz) diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs index c60e321219bd2..a85776a938b44 100644 --- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs +++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs @@ -10,7 +10,9 @@ // ignore-tidy-linelength -struct Foo<'x> { bar: isize } +use std::marker::PhantomData; + +struct Foo<'x> { bar: isize, marker: PhantomData<&'x ()> } fn foo1<'a>(x: &Foo) -> &'a isize { //~^ HELP: consider using an explicit lifetime parameter as shown: fn foo1<'a>(x: &'a Foo) -> &'a isize &x.bar //~ ERROR: cannot infer diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs index 3b96fd64fa200..73a58741bbbbc 100644 --- a/src/test/compile-fail/lint-missing-doc.rs +++ b/src/test/compile-fail/lint-missing-doc.rs @@ -47,20 +47,26 @@ fn foo3() {} /// dox pub trait A { /// dox - fn foo(); + fn foo(&self); /// dox - fn foo_with_impl() {} + fn foo_with_impl(&self) {} } + #[allow(missing_docs)] trait B { - fn foo(); - fn foo_with_impl() {} + fn foo(&self); + fn foo_with_impl(&self) {} } + pub trait C { //~ ERROR: missing documentation - fn foo(); //~ ERROR: missing documentation - fn foo_with_impl() {} //~ ERROR: missing documentation + fn foo(&self); //~ ERROR: missing documentation + fn foo_with_impl(&self) {} //~ ERROR: missing documentation +} + +#[allow(missing_docs)] +pub trait D { + fn dummy(&self) { } } -#[allow(missing_docs)] pub trait D {} impl Foo { pub fn foo() {} diff --git a/src/test/compile-fail/lint-non-camel-case-types.rs b/src/test/compile-fail/lint-non-camel-case-types.rs index 70d6b240985b0..9f58d5791cb0b 100644 --- a/src/test/compile-fail/lint-non-camel-case-types.rs +++ b/src/test/compile-fail/lint-non-camel-case-types.rs @@ -30,6 +30,7 @@ enum Foo5 { } trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6` + fn dummy(&self) { } } fn f(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name such as `Ty` diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs index f9cdfa4f7d685..88f2cbdea6d7b 100644 --- a/src/test/compile-fail/lint-stability.rs +++ b/src/test/compile-fail/lint-stability.rs @@ -341,7 +341,9 @@ mod this_crate { #[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] - pub trait DeprecatedTrait {} + pub trait DeprecatedTrait { + fn dummy(&self) { } + } struct S; diff --git a/src/test/compile-fail/lint-visible-private-types.rs b/src/test/compile-fail/lint-visible-private-types.rs index 8cf375f80fbb1..918b4ee209ca7 100644 --- a/src/test/compile-fail/lint-visible-private-types.rs +++ b/src/test/compile-fail/lint-visible-private-types.rs @@ -12,8 +12,10 @@ #![allow(dead_code)] #![crate_type="lib"] -struct Private; -pub struct Public; +use std::marker; + +struct Private(marker::PhantomData); +pub struct Public(marker::PhantomData); impl Private> { pub fn a(&self) -> Private { panic!() } @@ -103,7 +105,7 @@ impl PrivTrait for (Private,) { fn bar(&self) -> Private { panic!() } } -pub trait ParamTrait { +pub trait ParamTrait : marker::MarkerTrait { fn foo() -> T; } diff --git a/src/test/compile-fail/liveness-use-after-send.rs b/src/test/compile-fail/liveness-use-after-send.rs index a49339ecd7f28..03d8d62e0b4d5 100644 --- a/src/test/compile-fail/liveness-use-after-send.rs +++ b/src/test/compile-fail/liveness-use-after-send.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker; + fn send(ch: _chan, data: T) { println!("{:?}", ch); println!("{:?}", data); @@ -15,7 +17,7 @@ fn send(ch: _chan, data: T) { } #[derive(Debug)] -struct _chan(isize); +struct _chan(isize, marker::PhantomData); // Tests that "log(debug, message);" is flagged as using // message after the send deinitializes it diff --git a/src/test/compile-fail/map-types.rs b/src/test/compile-fail/map-types.rs index ba2205f5868d4..6e8719eeaceda 100644 --- a/src/test/compile-fail/map-types.rs +++ b/src/test/compile-fail/map-types.rs @@ -14,7 +14,10 @@ extern crate collections; use std::collections::HashMap; -trait Map {} +trait Map +{ + fn get(&self, k: K) -> V { panic!() } +} impl Map for HashMap {} diff --git a/src/test/compile-fail/method-ambig-one-trait-coerce.rs b/src/test/compile-fail/method-ambig-one-trait-coerce.rs deleted file mode 100644 index cb5da4bb54772..0000000000000 --- a/src/test/compile-fail/method-ambig-one-trait-coerce.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2012 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. - -// Test that when we pick a trait based on coercion, versus subtyping, -// we consider all possible coercions equivalent and don't try to pick -// a best one. - -trait Object { } - -trait foo { - fn foo(self) -> isize; -} - -impl foo for Box { - fn foo(self) -> isize {1} -} - -impl foo for Box { - fn foo(self) -> isize {2} -} - -fn test1(x: Box) { - // FIXME(#18737) -- we ought to consider this to be ambiguous, - // since we could coerce to either impl. However, what actually - // happens is that we consider both impls applicable because of - // incorrect subtyping relation. We then decide to call this a - // call to the `foo` trait, leading to the following error - // message. - - x.foo(); //~ ERROR `foo` is not implemented -} - -fn test2(x: Box) { - // Not ambiguous because it is a precise match: - x.foo(); -} - -fn test3(x: Box) { - // Not ambiguous because it is a precise match: - x.foo(); -} - -fn main() { } diff --git a/src/test/compile-fail/object-does-not-impl-trait.rs b/src/test/compile-fail/object-does-not-impl-trait.rs index cfaf149a49cac..607ab13d12201 100644 --- a/src/test/compile-fail/object-does-not-impl-trait.rs +++ b/src/test/compile-fail/object-does-not-impl-trait.rs @@ -11,8 +11,9 @@ // Test that an object type `Box` is not considered to implement the // trait `Foo`. Issue #5087. +use std::marker::MarkerTrait; -trait Foo {} +trait Foo : MarkerTrait {} fn take_foo(f: F) {} fn take_object(f: Box) { take_foo(f); } //~^ ERROR the trait `Foo` is not implemented diff --git a/src/test/compile-fail/object-lifetime-default-mybox.rs b/src/test/compile-fail/object-lifetime-default-mybox.rs index c107c8d131d3a..23ddea4499a72 100644 --- a/src/test/compile-fail/object-lifetime-default-mybox.rs +++ b/src/test/compile-fail/object-lifetime-default-mybox.rs @@ -37,7 +37,6 @@ fn load1<'a,'b>(a: &'a MyBox, a //~^ ERROR cannot infer //~| ERROR mismatched types - //~| ERROR mismatched types } fn main() { diff --git a/src/test/compile-fail/object-safety-no-static.rs b/src/test/compile-fail/object-safety-no-static.rs index 6a010d49692d2..aae829ec7b563 100644 --- a/src/test/compile-fail/object-safety-no-static.rs +++ b/src/test/compile-fail/object-safety-no-static.rs @@ -11,7 +11,7 @@ // Check that we correctly prevent users from making trait objects // from traits with static methods. -trait Foo { +trait Foo : ::std::marker::MarkerTrait { fn foo(); } diff --git a/src/test/compile-fail/on-unimplemented-bad-anno.rs b/src/test/compile-fail/on-unimplemented-bad-anno.rs index dda534cc489b5..7538b1c85e533 100644 --- a/src/test/compile-fail/on-unimplemented-bad-anno.rs +++ b/src/test/compile-fail/on-unimplemented-bad-anno.rs @@ -13,8 +13,12 @@ #![allow(unused)] +use std::marker; + #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"] -trait Foo{} +trait Foo + : marker::PhantomFn<(Self,Bar,Baz,Quux)> +{} #[rustc_on_unimplemented="a collection of type `{Self}` cannot be built from an iterator over elements of type `{A}`"] trait MyFromIterator { @@ -23,15 +27,21 @@ trait MyFromIterator { } #[rustc_on_unimplemented] //~ ERROR this attribute must have a value -trait BadAnnotation1 {} +trait BadAnnotation1 + : marker::MarkerTrait +{} #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"] //~^ ERROR there is no type parameter C on trait BadAnnotation2 -trait BadAnnotation2 {} +trait BadAnnotation2 + : marker::PhantomFn<(Self,A,B)> +{} #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"] //~^ only named substitution parameters are allowed -trait BadAnnotation3 {} +trait BadAnnotation3 + : marker::PhantomFn<(Self,A,B)> +{} pub fn main() { } diff --git a/src/test/compile-fail/on-unimplemented.rs b/src/test/compile-fail/on-unimplemented.rs index 7b406afcf1f58..2447d0864226a 100644 --- a/src/test/compile-fail/on-unimplemented.rs +++ b/src/test/compile-fail/on-unimplemented.rs @@ -11,8 +11,12 @@ #![feature(on_unimplemented)] +use std::marker; + #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"] -trait Foo{} +trait Foo + : marker::PhantomFn<(Self,Bar,Baz,Quux)> +{} fn foobar>() -> T { diff --git a/src/test/compile-fail/orphan-check-diagnostics.rs b/src/test/compile-fail/orphan-check-diagnostics.rs index ff5c101b9178f..8201565c3318d 100644 --- a/src/test/compile-fail/orphan-check-diagnostics.rs +++ b/src/test/compile-fail/orphan-check-diagnostics.rs @@ -15,7 +15,7 @@ extern crate orphan_check_diagnostics; use orphan_check_diagnostics::RemoteTrait; -trait LocalTrait {} +trait LocalTrait { fn dummy(&self) { } } impl RemoteTrait for T where T: LocalTrait {} //~^ ERROR type parameter `T` must be used as the type parameter for some local type diff --git a/src/test/compile-fail/priv-in-bad-locations.rs b/src/test/compile-fail/priv-in-bad-locations.rs index db649ed0cc606..43d112b8aa004 100644 --- a/src/test/compile-fail/priv-in-bad-locations.rs +++ b/src/test/compile-fail/priv-in-bad-locations.rs @@ -14,7 +14,7 @@ pub extern { } trait A { - fn foo() {} + fn foo(&self) {} } struct B; @@ -22,7 +22,7 @@ struct B; pub impl B {} //~ ERROR: unnecessary visibility pub impl A for B { //~ ERROR: unnecessary visibility - pub fn foo() {} //~ ERROR: unnecessary visibility + pub fn foo(&self) {} //~ ERROR: unnecessary visibility } pub fn main() {} diff --git a/src/test/compile-fail/privacy-ns2.rs b/src/test/compile-fail/privacy-ns2.rs index 7fe0574ab7d9a..67bb566ea682c 100644 --- a/src/test/compile-fail/privacy-ns2.rs +++ b/src/test/compile-fail/privacy-ns2.rs @@ -17,7 +17,9 @@ // public type, private value pub mod foo1 { - pub trait Bar { + use std::marker::MarkerTrait; + + pub trait Bar : MarkerTrait { } pub struct Baz; @@ -39,7 +41,7 @@ fn test_list1() { // private type, public value pub mod foo2 { - trait Bar { + trait Bar : ::std::marker::MarkerTrait { } pub struct Baz; @@ -60,7 +62,7 @@ fn test_list2() { // neither public pub mod foo3 { - trait Bar { + trait Bar : ::std::marker::MarkerTrait { } pub struct Baz; diff --git a/src/test/compile-fail/privacy1.rs b/src/test/compile-fail/privacy1.rs index 7ebbcc2809a58..1ae79adbad76a 100644 --- a/src/test/compile-fail/privacy1.rs +++ b/src/test/compile-fail/privacy1.rs @@ -11,11 +11,15 @@ #![feature(lang_items, start, no_std)] #![no_std] // makes debugging this test *a lot* easier (during resolve) +#[lang="phantom_fn"] +pub trait PhantomFn { } +impl PhantomFn for U { } + #[lang="sized"] -pub trait Sized {} +pub trait Sized : PhantomFn {} #[lang="copy"] -pub trait Copy {} +pub trait Copy : PhantomFn {} mod bar { // shouldn't bring in too much diff --git a/src/test/compile-fail/privacy4.rs b/src/test/compile-fail/privacy4.rs index bcb46663aa849..adce93af0794f 100644 --- a/src/test/compile-fail/privacy4.rs +++ b/src/test/compile-fail/privacy4.rs @@ -11,8 +11,12 @@ #![feature(lang_items, start, no_std)] #![no_std] // makes debugging this test *a lot* easier (during resolve) -#[lang = "sized"] pub trait Sized {} -#[lang="copy"] pub trait Copy {} +#[lang="phantom_fn"] +pub trait PhantomFn { } +impl PhantomFn for U { } + +#[lang = "sized"] pub trait Sized : PhantomFn {} +#[lang="copy"] pub trait Copy : PhantomFn {} // Test to make sure that private items imported through globs remain private // when they're used. diff --git a/src/test/compile-fail/region-object-lifetime-in-coercion.rs b/src/test/compile-fail/region-object-lifetime-in-coercion.rs index 20cc624ab1904..2da414befd897 100644 --- a/src/test/compile-fail/region-object-lifetime-in-coercion.rs +++ b/src/test/compile-fail/region-object-lifetime-in-coercion.rs @@ -13,7 +13,7 @@ #![feature(box_syntax)] -trait Foo {} +trait Foo : ::std::marker::MarkerTrait {} impl<'a> Foo for &'a [u8] {} fn a(v: &[u8]) -> Box { diff --git a/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs b/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs index f833361e3b505..f921eccef1f8c 100644 --- a/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs +++ b/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs @@ -11,7 +11,10 @@ // Test that the compiler checks that arbitrary region bounds declared // in the trait must be satisfied on the impl. Issue #20890. -trait Foo<'a> { type Value: 'a; } +trait Foo<'a> { + type Value: 'a; + fn dummy(&'a self) { } +} impl<'a> Foo<'a> for &'a i16 { // OK. diff --git a/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs b/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs index 0871d8b01f6e4..1cf83b8ac585f 100644 --- a/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs +++ b/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs @@ -11,7 +11,10 @@ // Test that the compiler checks that the 'static bound declared in // the trait must be satisfied on the impl. Issue #20890. -trait Foo { type Value: 'static; } +trait Foo { + type Value: 'static; + fn dummy(&self) { } +} impl<'a> Foo for &'a i32 { //~^ ERROR cannot infer diff --git a/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs b/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs index a3c38dff6b0f6..278ccd3c11936 100644 --- a/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs +++ b/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs @@ -21,10 +21,9 @@ pub trait Foo<'a, 't> { fn has_bound<'b:'a>(self, b: Inv<'b>); fn wrong_bound1<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); fn okay_bound<'b,'c,'d:'a+'b+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); - fn another_bound<'x: 'a>(self, x: Inv<'x>); + fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>); } - impl<'a, 't> Foo<'a, 't> for &'a isize { fn no_bound<'b:'a>(self, b: Inv<'b>) { //~^ ERROR lifetime parameters or bounds on method `no_bound` do not match @@ -51,7 +50,7 @@ impl<'a, 't> Foo<'a, 't> for &'a isize { fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) { } - fn another_bound<'x: 't>(self, x: Inv<'x>) {} + fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {} } fn main() { } diff --git a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs index 74c2c6e584b43..f13d8a60894cb 100644 --- a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs +++ b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs @@ -8,16 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(lang_items, no_std)] -#![no_std] - // Check that explicit region bounds are allowed on the various // nominal types (but not on other types) and that they are type // checked. -#[lang="sized"] -trait Sized { } - struct Inv<'a> { // invariant w/r/t 'a x: &'a mut &'a isize } diff --git a/src/test/compile-fail/regions-close-associated-type-into-object.rs b/src/test/compile-fail/regions-close-associated-type-into-object.rs index 8a03f36972dd1..979c1e997d03c 100644 --- a/src/test/compile-fail/regions-close-associated-type-into-object.rs +++ b/src/test/compile-fail/regions-close-associated-type-into-object.rs @@ -10,7 +10,9 @@ #![feature(box_syntax)] -trait X {} +use std::marker::MarkerTrait; + +trait X : MarkerTrait {} trait Iter { type Item: X; diff --git a/src/test/compile-fail/regions-close-object-into-object-1.rs b/src/test/compile-fail/regions-close-object-into-object-1.rs index 7a0e3cf4611c7..7bbce7dad530d 100644 --- a/src/test/compile-fail/regions-close-object-into-object-1.rs +++ b/src/test/compile-fail/regions-close-object-into-object-1.rs @@ -11,13 +11,16 @@ #![feature(box_syntax)] #![allow(warnings)] -trait A {} +use std::marker::PhantomFn; + +trait A : PhantomFn<(Self,T)> { } struct B<'a, T>(&'a (A+'a)); -trait X {} +trait X : ::std::marker::MarkerTrait {} + impl<'a, T> X for B<'a, T> {} -fn f<'a, T, U>(v: Box+'static>) -> Box { +fn f<'a, T:'static, U>(v: Box+'static>) -> Box { box B(&*v) as Box //~ ERROR `*v` does not live long enough } diff --git a/src/test/compile-fail/regions-close-object-into-object-2.rs b/src/test/compile-fail/regions-close-object-into-object-2.rs index 7861fb95fef66..6de49020a6fbb 100644 --- a/src/test/compile-fail/regions-close-object-into-object-2.rs +++ b/src/test/compile-fail/regions-close-object-into-object-2.rs @@ -10,10 +10,12 @@ #![feature(box_syntax)] -trait A {} +use std::marker::PhantomFn; + +trait A : PhantomFn<(Self,T)> { } struct B<'a, T>(&'a (A+'a)); -trait X {} +trait X : PhantomFn {} impl<'a, T> X for B<'a, T> {} fn g<'a, T: 'static>(v: Box+'a>) -> Box { diff --git a/src/test/compile-fail/regions-close-object-into-object-3.rs b/src/test/compile-fail/regions-close-object-into-object-3.rs index 31354de2a27df..e22d0c7d0a4f5 100644 --- a/src/test/compile-fail/regions-close-object-into-object-3.rs +++ b/src/test/compile-fail/regions-close-object-into-object-3.rs @@ -11,10 +11,12 @@ #![feature(box_syntax)] #![allow(warnings)] -trait A {} +use std::marker::PhantomFn; + +trait A : PhantomFn<(Self,T)> {} struct B<'a, T>(&'a (A+'a)); -trait X {} +trait X : PhantomFn {} impl<'a, T> X for B<'a, T> {} fn h<'a, T, U>(v: Box+'static>) -> Box { diff --git a/src/test/compile-fail/regions-close-object-into-object-4.rs b/src/test/compile-fail/regions-close-object-into-object-4.rs index c60975f97e13d..147a575d38cac 100644 --- a/src/test/compile-fail/regions-close-object-into-object-4.rs +++ b/src/test/compile-fail/regions-close-object-into-object-4.rs @@ -10,10 +10,12 @@ #![feature(box_syntax)] -trait A {} +use std::marker::PhantomFn; + +trait A : PhantomFn<(Self,T)> {} struct B<'a, T>(&'a (A+'a)); -trait X {} +trait X : PhantomFn {} impl<'a, T> X for B<'a, T> {} fn i<'a, T, U>(v: Box+'a>) -> Box { diff --git a/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs b/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs index 25b8137d29cad..2341d2397c9b0 100644 --- a/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs +++ b/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs @@ -10,7 +10,9 @@ #![feature(box_syntax)] -trait Foo { } +use std::marker::MarkerTrait; + +trait Foo : MarkerTrait { } impl<'a> Foo for &'a isize { } diff --git a/src/test/compile-fail/regions-close-param-into-object.rs b/src/test/compile-fail/regions-close-param-into-object.rs index 74b36958c92f1..9ad49a6703ee3 100644 --- a/src/test/compile-fail/regions-close-param-into-object.rs +++ b/src/test/compile-fail/regions-close-param-into-object.rs @@ -10,7 +10,7 @@ #![feature(box_syntax)] -trait X {} +trait X : ::std::marker::MarkerTrait {} fn p1(v: T) -> Box where T : X diff --git a/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs index 6c5e90a54de2b..b7ef19d1e3bfc 100644 --- a/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs +++ b/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs @@ -20,7 +20,7 @@ use std::marker; // Contravariant<'foo> <: Contravariant<'static> because // 'foo <= 'static struct Contravariant<'a> { - marker: marker::ContravariantLifetime<'a> + marker: marker::PhantomData<&'a()> } fn use_<'short,'long>(c: Contravariant<'short>, diff --git a/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs index d8e31fa1374a8..0d3d9dacbd6f6 100644 --- a/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs +++ b/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs @@ -17,7 +17,7 @@ use std::marker; struct Covariant<'a> { - marker: marker::CovariantLifetime<'a> + marker: marker::PhantomData } fn use_<'short,'long>(c: Covariant<'long>, diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs index 5f4a1af6bf90f..65decb4da1b99 100644 --- a/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs +++ b/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs @@ -11,7 +11,7 @@ use std::marker; struct invariant<'a> { - marker: marker::InvariantLifetime<'a> + marker: marker::PhantomData<*mut &'a()> } fn to_same_lifetime<'r>(bi: invariant<'r>) { diff --git a/src/test/compile-fail/required-lang-item.rs b/src/test/compile-fail/required-lang-item.rs index 7d252604883d6..1b749faf1b8b9 100644 --- a/src/test/compile-fail/required-lang-item.rs +++ b/src/test/compile-fail/required-lang-item.rs @@ -11,7 +11,11 @@ #![feature(lang_items, no_std)] #![no_std] -#[lang="sized"] pub trait Sized {} +#[lang="phantom_fn"] +pub trait PhantomFn { } +impl PhantomFn for U { } + +#[lang="sized"] pub trait Sized : PhantomFn {} // error-pattern:requires `start` lang_item diff --git a/src/test/compile-fail/shadowed-type-parameter.rs b/src/test/compile-fail/shadowed-type-parameter.rs index 1a3d7821159c3..1f72db1e894fa 100644 --- a/src/test/compile-fail/shadowed-type-parameter.rs +++ b/src/test/compile-fail/shadowed-type-parameter.rs @@ -12,19 +12,21 @@ #![feature(box_syntax)] -struct Foo; +struct Foo(T); impl Foo { fn shadow_in_method(&self) {} //~^ ERROR type parameter `T` shadows another type parameter fn not_shadow_in_item(&self) { - struct Bar; // not a shadow, separate item + struct Bar(T,U); // not a shadow, separate item fn foo() {} // same } } trait Bar { + fn dummy(&self) -> T; + fn shadow_in_required(&self); //~^ ERROR type parameter `T` shadows another type parameter diff --git a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs index 1203d62234899..3c1c3796a246f 100644 --- a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs +++ b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs @@ -8,10 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Foo(T); +use std::marker; + +struct Foo(T, marker::PhantomData); fn main() { - match Foo(1.1) { + match Foo(1.1, marker::PhantomData) { 1 => {} //~^ ERROR mismatched types //~| expected `Foo<_, _>` diff --git a/src/test/compile-fail/staticness-mismatch.rs b/src/test/compile-fail/staticness-mismatch.rs index bf4e46cace304..2dfc9b79ee20a 100644 --- a/src/test/compile-fail/staticness-mismatch.rs +++ b/src/test/compile-fail/staticness-mismatch.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - trait foo { + fn dummy(&self) { } fn bar(); } diff --git a/src/test/compile-fail/trait-as-struct-constructor.rs b/src/test/compile-fail/trait-as-struct-constructor.rs index a1fcab002e138..fff144140947a 100644 --- a/src/test/compile-fail/trait-as-struct-constructor.rs +++ b/src/test/compile-fail/trait-as-struct-constructor.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait TraitNotAStruct { } +trait TraitNotAStruct : ::std::marker::MarkerTrait { } fn main() { TraitNotAStruct{ value: 0 }; diff --git a/src/test/compile-fail/trait-bounds-cant-coerce.rs b/src/test/compile-fail/trait-bounds-cant-coerce.rs index 79174552ae09c..3129dceffbb66 100644 --- a/src/test/compile-fail/trait-bounds-cant-coerce.rs +++ b/src/test/compile-fail/trait-bounds-cant-coerce.rs @@ -10,6 +10,7 @@ trait Foo { + fn dummy(&self) { } } fn a(_x: Box) { diff --git a/src/test/compile-fail/trait-bounds-impl-comparison-1.rs b/src/test/compile-fail/trait-bounds-impl-comparison-1.rs index 477bd4f5be9a1..34e06cc93658a 100644 --- a/src/test/compile-fail/trait-bounds-impl-comparison-1.rs +++ b/src/test/compile-fail/trait-bounds-impl-comparison-1.rs @@ -11,7 +11,10 @@ // Make sure rustc checks the type parameter bounds in implementations of traits, // see #2687 -trait A {} +use std::marker; + +trait A : marker::PhantomFn { +} trait B: A {} @@ -62,15 +65,16 @@ impl Foo for isize { //~^ ERROR the requirement `T : C` appears on the impl } - -trait Getter { } +trait Getter { + fn get(&self) -> T { loop { } } +} trait Trait { - fn method>(); + fn method>(&self); } impl Trait for usize { - fn method>() {} + fn method>(&self) {} //~^ G : Getter` appears on the impl method but not on the corresponding trait method } diff --git a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs index 8ad19116e7bb1..284c4fac953f2 100644 --- a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs +++ b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs @@ -14,7 +14,9 @@ trait Iterator { fn next(&mut self) -> Option; } -trait IteratorUtil { +trait IteratorUtil + : ::std::marker::PhantomFn<(),A> +{ fn zip>(self, other: U) -> ZipIterator; } diff --git a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs index 434d803d718e7..448b186f6a5c6 100644 --- a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs +++ b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs @@ -9,6 +9,7 @@ // except according to those terms. trait Foo { + fn dummy(&self) { } } // This should emit the less confusing error, not the more confusing one. diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs index 118dfeb37c251..df44e847c50fd 100644 --- a/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs +++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Trait {} +trait Trait { + fn dummy(&self) { } +} struct Foo { x: T, diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs index d5369817e9ac1..18871d0d386d7 100644 --- a/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs +++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Trait {} +trait Trait { + fn dummy(&self) { } +} struct Foo { x: T, diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs index 490ee0e8ad6f3..8dfdb2f205d6f 100644 --- a/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs +++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Trait {} +use std::marker::MarkerTrait; + +trait Trait : MarkerTrait {} struct Foo { x: T, @@ -51,15 +53,15 @@ enum MoreBadness { EvenMoreBadness(Bar), } -trait PolyTrait { - fn whatever() {} +trait PolyTrait +{ + fn whatever(&self, t: T) {} } struct Struct; impl PolyTrait> for Struct { //~^ ERROR not implemented - fn whatever() {} } fn main() { diff --git a/src/test/compile-fail/trait-bounds-sugar.rs b/src/test/compile-fail/trait-bounds-sugar.rs index 3d264e681a3d2..e4058a0943aad 100644 --- a/src/test/compile-fail/trait-bounds-sugar.rs +++ b/src/test/compile-fail/trait-bounds-sugar.rs @@ -10,8 +10,9 @@ // Tests for "default" bounds inferred for traits with no bounds list. +use std::marker::MarkerTrait; -trait Foo {} +trait Foo : MarkerTrait {} fn a(_x: Box) { } diff --git a/src/test/compile-fail/trait-impl-1.rs b/src/test/compile-fail/trait-impl-1.rs index dadcbd5bce710..2f4793b4d888f 100644 --- a/src/test/compile-fail/trait-impl-1.rs +++ b/src/test/compile-fail/trait-impl-1.rs @@ -12,7 +12,9 @@ // trait impl is only applied to a trait object, not concrete types which implement // the trait. -trait T {} +use std::marker::MarkerTrait; + +trait T : MarkerTrait {} impl<'a> T+'a { fn foo(&self) {} diff --git a/src/test/compile-fail/trait-object-safety.rs b/src/test/compile-fail/trait-object-safety.rs index 761bcd4968abf..d45d13556e121 100644 --- a/src/test/compile-fail/trait-object-safety.rs +++ b/src/test/compile-fail/trait-object-safety.rs @@ -12,6 +12,7 @@ trait Tr { fn foo(); + fn bar(&self) { } } struct St; diff --git a/src/test/compile-fail/trait-static-method-generic-inference.rs b/src/test/compile-fail/trait-static-method-generic-inference.rs index 651f663fc9913..0e357d9d4d531 100644 --- a/src/test/compile-fail/trait-static-method-generic-inference.rs +++ b/src/test/compile-fail/trait-static-method-generic-inference.rs @@ -16,6 +16,7 @@ mod base { pub trait HasNew { fn new() -> T; + fn dummy(&self) { } } pub struct Foo { diff --git a/src/test/compile-fail/typeck-negative-impls-builtin.rs b/src/test/compile-fail/typeck-negative-impls-builtin.rs index 9da79b11cf0b7..557fb2f4f8833 100644 --- a/src/test/compile-fail/typeck-negative-impls-builtin.rs +++ b/src/test/compile-fail/typeck-negative-impls-builtin.rs @@ -12,7 +12,9 @@ struct TestType; -trait TestTrait {} +trait TestTrait { + fn dummy(&self) { } +} impl !TestTrait for TestType {} //~^ ERROR negative impls are currently allowed just for `Send` and `Sync` diff --git a/src/test/compile-fail/typeck_type_placeholder_mismatch.rs b/src/test/compile-fail/typeck_type_placeholder_mismatch.rs index a34be63ba6b3c..1daea8f915b3f 100644 --- a/src/test/compile-fail/typeck_type_placeholder_mismatch.rs +++ b/src/test/compile-fail/typeck_type_placeholder_mismatch.rs @@ -11,14 +11,16 @@ // This test checks that genuine type errors with partial // type hints are understandable. -struct Foo; -struct Bar; +use std::marker::PhantomData; + +struct Foo(PhantomData); +struct Bar(PhantomData); pub fn main() { } fn test1() { - let x: Foo<_> = Bar::; + let x: Foo<_> = Bar::(PhantomData); //~^ ERROR mismatched types //~| expected `Foo<_>` //~| found `Bar` @@ -28,7 +30,7 @@ fn test1() { } fn test2() { - let x: Foo<_> = Bar::; + let x: Foo<_> = Bar::(PhantomData); //~^ ERROR mismatched types //~| expected `Foo<_>` //~| found `Bar` diff --git a/src/test/compile-fail/unboxed-closure-feature-gate.rs b/src/test/compile-fail/unboxed-closure-feature-gate.rs index 3536244f01165..74a6f869f63fb 100644 --- a/src/test/compile-fail/unboxed-closure-feature-gate.rs +++ b/src/test/compile-fail/unboxed-closure-feature-gate.rs @@ -11,8 +11,12 @@ // Check that parenthetical notation is feature-gated except with the // `Fn` traits. +use std::marker; + trait Foo { type Output; + + fn dummy(&self, a: A) { } } fn main() { diff --git a/src/test/compile-fail/unboxed-closure-sugar-default.rs b/src/test/compile-fail/unboxed-closure-sugar-default.rs index 870377bc1add7..831db98941c6d 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-default.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-default.rs @@ -19,7 +19,7 @@ trait Foo { fn dummy(&self, t: T, v: V); } -trait Eq { } +trait Eq { fn same_types(&self, x: &X) -> bool { true } } impl Eq for X { } fn eq() where A : Eq { } diff --git a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs index dc5576aee650a..6d315c1b7a996 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs @@ -16,12 +16,14 @@ #![feature(unboxed_closures)] #![allow(dead_code)] +use std::marker::PhantomFn; + trait Foo { type Output; fn dummy(&self, t: T, u: Self::Output); } -trait Eq { } +trait Eq : PhantomFn<(Self,X)> { } impl Eq for X { } fn eq>() { } diff --git a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs index d2f781bba11ea..bd3530e6e3026 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs @@ -16,12 +16,14 @@ #![feature(unboxed_closures)] #![allow(dead_code)] +use std::marker; + trait Foo { type Output; fn dummy(&self, t: T); } -trait Eq { } +trait Eq : marker::PhantomFn<(Self, X)> { } impl Eq for X { } fn eq>() { } diff --git a/src/test/compile-fail/unboxed-closure-sugar-region.rs b/src/test/compile-fail/unboxed-closure-sugar-region.rs index 75688e44e8076..057b496bd43eb 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-region.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-region.rs @@ -22,7 +22,7 @@ trait Foo<'a,T> { fn dummy(&'a self) -> &'a (T,Self::Output); } -trait Eq { } +trait Eq { fn is_of_eq_type(&self, x: &X) -> bool { true } } impl Eq for X { } fn eq>() { } diff --git a/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs b/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs index 215b2c6798e40..713b64b1349fc 100644 --- a/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs +++ b/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs @@ -10,7 +10,7 @@ #![feature(core,unboxed_closures)] -use std::marker::CovariantType; +use std::marker::PhantomData; // A erroneous variant of `run-pass/unboxed_closures-infer-recursive-fn.rs` // where we attempt to perform mutation in the recursive function. This fails to compile @@ -18,12 +18,12 @@ use std::marker::CovariantType; struct YCombinator { func: F, - marker: CovariantType<(A,R)>, + marker: PhantomData<(A,R)>, } impl YCombinator { fn new(f: F) -> YCombinator { - YCombinator { func: f, marker: CovariantType } + YCombinator { func: f, marker: PhantomData } } } diff --git a/src/test/compile-fail/unnecessary-private.rs b/src/test/compile-fail/unnecessary-private.rs index e3707292f2495..964db6e9a4546 100644 --- a/src/test/compile-fail/unnecessary-private.rs +++ b/src/test/compile-fail/unnecessary-private.rs @@ -13,10 +13,10 @@ fn main() { pub struct A; //~ ERROR: visibility has no effect pub enum B {} //~ ERROR: visibility has no effect pub trait C { //~ ERROR: visibility has no effect - pub fn foo() {} //~ ERROR: visibility has no effect + pub fn foo(&self) {} //~ ERROR: visibility has no effect } impl A { - pub fn foo() {} //~ ERROR: visibility has no effect + pub fn foo(&self) {} //~ ERROR: visibility has no effect } struct D { diff --git a/src/test/compile-fail/unsized-inherent-impl-self-type.rs b/src/test/compile-fail/unsized-inherent-impl-self-type.rs index 8740346a21750..a03c76b12dd8e 100644 --- a/src/test/compile-fail/unsized-inherent-impl-self-type.rs +++ b/src/test/compile-fail/unsized-inherent-impl-self-type.rs @@ -12,7 +12,7 @@ // impl - struct -struct S5; +struct S5(Y); impl S5 { //~ ERROR not implemented } diff --git a/src/test/compile-fail/unsized-trait-impl-self-type.rs b/src/test/compile-fail/unsized-trait-impl-self-type.rs index 3dd55b0ba7d23..08df1d9b7b8fb 100644 --- a/src/test/compile-fail/unsized-trait-impl-self-type.rs +++ b/src/test/compile-fail/unsized-trait-impl-self-type.rs @@ -12,9 +12,10 @@ // impl - struct trait T3 { + fn foo(&self, z: &Z); } -struct S5; +struct S5(Y); impl T3 for S5 { //~ ERROR not implemented } diff --git a/src/test/compile-fail/unsized-trait-impl-trait-arg.rs b/src/test/compile-fail/unsized-trait-impl-trait-arg.rs index ac8043d6852a9..4723dfeaeb988 100644 --- a/src/test/compile-fail/unsized-trait-impl-trait-arg.rs +++ b/src/test/compile-fail/unsized-trait-impl-trait-arg.rs @@ -12,8 +12,9 @@ // impl - unbounded trait T2 { + fn foo(&self, z: Z); } -struct S4; +struct S4(Box); impl T2 for S4 { //~^ ERROR `core::marker::Sized` is not implemented for the type `X` } diff --git a/src/test/compile-fail/unsized3.rs b/src/test/compile-fail/unsized3.rs index 4fc76c99c60b7..de1cbab82b281 100644 --- a/src/test/compile-fail/unsized3.rs +++ b/src/test/compile-fail/unsized3.rs @@ -10,6 +10,7 @@ // Test sized-ness checking in substitution within fn bodies.. +use std::marker; // Unbounded. fn f1(x: &X) { @@ -20,7 +21,9 @@ fn f2(x: &X) { } // Bounded. -trait T {} +trait T { + fn foo(&self) { } +} fn f3(x: &X) { f4::(x); //~^ ERROR the trait `core::marker::Sized` is not implemented diff --git a/src/test/compile-fail/unsized6.rs b/src/test/compile-fail/unsized6.rs index 217d1f44d8461..f31a6ffdc0d7c 100644 --- a/src/test/compile-fail/unsized6.rs +++ b/src/test/compile-fail/unsized6.rs @@ -10,8 +10,9 @@ // Test `?Sized` local variables. +use std::marker; -trait T {} +trait T : marker::MarkerTrait { } fn f1(x: &X) { let _: X; // <-- this is OK, no bindings created, no initializer. diff --git a/src/test/compile-fail/unsized7.rs b/src/test/compile-fail/unsized7.rs index 6fc547c0b8e86..6ea3d0720eeeb 100644 --- a/src/test/compile-fail/unsized7.rs +++ b/src/test/compile-fail/unsized7.rs @@ -10,13 +10,17 @@ // Test sized-ness checking in substitution in impls. -trait T {} +use std::marker::MarkerTrait; + +trait T : MarkerTrait {} // I would like these to fail eventually. // impl - bounded trait T1 { + fn dummy(&self) -> Z; } -struct S3; + +struct S3(Box); impl T1 for S3 { //~^ ERROR `core::marker::Sized` is not implemented for the type `X` } diff --git a/src/test/compile-fail/unused-attr.rs b/src/test/compile-fail/unused-attr.rs index 2d4bc0c857a9a..af242b96a84a1 100644 --- a/src/test/compile-fail/unused-attr.rs +++ b/src/test/compile-fail/unused-attr.rs @@ -52,9 +52,9 @@ struct Foo { #[foo] //~ ERROR unused attribute trait Baz { #[foo] //~ ERROR unused attribute - fn blah(); + fn blah(&self); #[foo] //~ ERROR unused attribute - fn blah2() {} + fn blah2(&self) {} } fn main() {} diff --git a/src/test/compile-fail/useless-priv.rs b/src/test/compile-fail/useless-priv.rs index d8531f4543dff..b1120e54434eb 100644 --- a/src/test/compile-fail/useless-priv.rs +++ b/src/test/compile-fail/useless-priv.rs @@ -12,12 +12,14 @@ struct A { pub i: isize } pub enum C { pub Variant } //~ ERROR: unnecessary `pub` pub trait E { - pub fn foo() {} //~ ERROR: unnecessary visibility + pub fn foo(&self) {} //~ ERROR: unnecessary visibility +} +trait F { + pub fn foo(&self) {} //~ ERROR: unnecessary visibility } -trait F { pub fn foo() {} } //~ ERROR: unnecessary visibility impl E for A { - pub fn foo() {} //~ ERROR: unnecessary visibility + pub fn foo(&self) {} //~ ERROR: unnecessary visibility } fn main() {} diff --git a/src/test/compile-fail/useless-priv2.rs b/src/test/compile-fail/useless-priv2.rs index 7125a66b294ce..a404d09248f01 100644 --- a/src/test/compile-fail/useless-priv2.rs +++ b/src/test/compile-fail/useless-priv2.rs @@ -9,8 +9,10 @@ // except according to those terms. pub trait E { - pub fn foo(); //~ ERROR: unnecessary visibility + pub fn foo(&self); //~ ERROR: unnecessary visibility +} +trait F { + pub fn foo(&self); //~ ERROR: unnecessary visibility } -trait F { pub fn foo(); } //~ ERROR: unnecessary visibility fn main() {} diff --git a/src/test/compile-fail/variance-regions-direct.rs b/src/test/compile-fail/variance-regions-direct.rs index d70305d1106ec..da4d6c75227fc 100644 --- a/src/test/compile-fail/variance-regions-direct.rs +++ b/src/test/compile-fail/variance-regions-direct.rs @@ -60,6 +60,7 @@ struct Test6<'a, 'b> { //~ ERROR regions=[[-, o];[];[]] #[rustc_variance] struct Test7<'a> { //~ ERROR regions=[[*];[];[]] + //~^ ERROR parameter `'a` is never used x: isize } diff --git a/src/test/compile-fail/variance-regions-indirect.rs b/src/test/compile-fail/variance-regions-indirect.rs index 4bb329d6304cf..9beb90d0b2483 100644 --- a/src/test/compile-fail/variance-regions-indirect.rs +++ b/src/test/compile-fail/variance-regions-indirect.rs @@ -16,6 +16,7 @@ #[rustc_variance] enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[]] + //~^ ERROR parameter `'d` is never used Test8A(extern "Rust" fn(&'a isize)), Test8B(&'b [isize]), Test8C(&'b mut &'c str), @@ -23,16 +24,19 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[]] #[rustc_variance] struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[*, o, -, +];[];[]] + //~^ ERROR parameter `'w` is never used f: Base<'z, 'y, 'x, 'w> } #[rustc_variance] // Combine - and + to yield o struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[[o, o, *];[];[]] + //~^ ERROR parameter `'c` is never used f: Base<'a, 'a, 'b, 'c> } #[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here) struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[[o, -, *];[];[]] + //~^ ERROR parameter `'c` is never used f: Base<'a, 'b, 'a, 'c> } diff --git a/src/test/compile-fail/variance-trait-object-bound.rs b/src/test/compile-fail/variance-trait-object-bound.rs index 965b9430a5e2d..f0ca1edd56387 100644 --- a/src/test/compile-fail/variance-trait-object-bound.rs +++ b/src/test/compile-fail/variance-trait-object-bound.rs @@ -18,7 +18,7 @@ use std::mem; -trait T { fn foo(); } +trait T { fn foo(&self); } #[rustc_variance] struct TOption<'a> { //~ ERROR regions=[[-];[];[]] diff --git a/src/test/compile-fail/visible-private-types-generics.rs b/src/test/compile-fail/visible-private-types-generics.rs index 7ff18f8e0886c..1f2205b5c7198 100644 --- a/src/test/compile-fail/visible-private-types-generics.rs +++ b/src/test/compile-fail/visible-private-types-generics.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo {} +trait Foo { + fn dummy(&self) { } +} pub fn f< T diff --git a/src/test/compile-fail/visible-private-types-supertrait.rs b/src/test/compile-fail/visible-private-types-supertrait.rs index dc6d446154ac7..9d9eae4a0759b 100644 --- a/src/test/compile-fail/visible-private-types-supertrait.rs +++ b/src/test/compile-fail/visible-private-types-supertrait.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo {} +trait Foo { + fn dummy(&self) { } +} pub trait Bar : Foo {} //~ ERROR private trait in exported type diff --git a/src/test/compile-fail/where-clause-method-substituion.rs b/src/test/compile-fail/where-clause-method-substituion.rs index a5108f005dc0e..bf614e6eb512b 100644 --- a/src/test/compile-fail/where-clause-method-substituion.rs +++ b/src/test/compile-fail/where-clause-method-substituion.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo {} +trait Foo { + fn dummy(&self, t: T) { } +} trait Bar { fn method(&self) where A: Foo; diff --git a/src/test/compile-fail/where-clauses-not-parameter.rs b/src/test/compile-fail/where-clauses-not-parameter.rs index 313ae273c07fe..7968cc37090ac 100644 --- a/src/test/compile-fail/where-clauses-not-parameter.rs +++ b/src/test/compile-fail/where-clauses-not-parameter.rs @@ -21,7 +21,7 @@ fn test2() -> bool where Option : Eq {} #[derive(PartialEq)] //~^ ERROR cannot bound type `isize`, where clause bounds -enum Foo where isize : Eq { MkFoo } +enum Foo where isize : Eq { MkFoo(T) } //~^ ERROR cannot bound type `isize`, where clause bounds fn test3() -> bool where Option> : Eq {} @@ -31,7 +31,7 @@ fn test4() -> bool where Option> : Eq {} trait Baz where isize : Eq { //~^ ERROR cannot bound type `isize`, where clause bounds may only - fn baz() where String : Eq; //~ ERROR cannot bound type `collections::string::String` + fn baz(&self, t: T) where String : Eq; //~ ERROR cannot bound type `collections::string::String` //~^ ERROR cannot bound type `isize`, where clause } diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs index adc4711b49aa2..cb1cf8c55579a 100644 --- a/src/test/debuginfo/type-names.rs +++ b/src/test/debuginfo/type-names.rs @@ -177,10 +177,11 @@ #![omit_gdb_pretty_printer_section] use self::Enum1::{Variant1_1, Variant1_2}; +use std::marker::PhantomData; use std::ptr; struct Struct1; -struct GenericStruct; +struct GenericStruct(PhantomData<(T1,T2)>); enum Enum1 { Variant1_1, @@ -207,8 +208,8 @@ mod Mod1 { } } -trait Trait1 { } -trait Trait2 { } +trait Trait1 { fn dummy(&self) { } } +trait Trait2 { fn dummy(&self, _: T1, _:T2) { } } impl Trait1 for isize {} impl Trait2 for isize {} @@ -240,8 +241,10 @@ fn main() { // Structs let simple_struct = Struct1; - let generic_struct1: GenericStruct = GenericStruct; - let generic_struct2: GenericStruct usize> = GenericStruct; + let generic_struct1: GenericStruct = + GenericStruct(PhantomData); + let generic_struct2: GenericStruct usize> = + GenericStruct(PhantomData); let mod_struct = Mod1::Struct2; // Enums @@ -262,10 +265,10 @@ fn main() { // References let ref1 = (&Struct1, 0i32); - let ref2 = (&GenericStruct::, 0i32); + let ref2 = (&GenericStruct::(PhantomData), 0i32); let mut mut_struct1 = Struct1; - let mut mut_generic_struct = GenericStruct::; + let mut mut_generic_struct = GenericStruct::(PhantomData); let mut_ref1 = (&mut mut_struct1, 0i32); let mut_ref2 = (&mut mut_generic_struct, 0i32); diff --git a/src/test/pretty/empty-impl.rs b/src/test/pretty/empty-impl.rs index f22f1b4095269..f5205de5c1fcd 100644 --- a/src/test/pretty/empty-impl.rs +++ b/src/test/pretty/empty-impl.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait X { } +trait X { fn dummy(&self) { } } impl X for uint { } -trait Y { } +trait Y { fn dummy(&self) { } } impl Y for uint { } diff --git a/src/test/pretty/path-type-bounds.rs b/src/test/pretty/path-type-bounds.rs index e27a3365a4105..9e1f2aa8bfe01 100644 --- a/src/test/pretty/path-type-bounds.rs +++ b/src/test/pretty/path-type-bounds.rs @@ -11,7 +11,9 @@ // pp-exact -trait Tr { } +trait Tr { + fn dummy(&self) { } +} impl Tr for int { } fn foo<'a>(x: Box) -> Box { x } diff --git a/src/test/run-fail/bug-811.rs b/src/test/run-fail/bug-811.rs index e46564f80760c..4ad81197286bb 100644 --- a/src/test/run-fail/bug-811.rs +++ b/src/test/run-fail/bug-811.rs @@ -9,6 +9,9 @@ // except according to those terms. // error-pattern:quux + +use std::marker::PhantomData; + fn test00_start(ch: chan_t, message: int) { send(ch, message); } type task_id = int; @@ -17,6 +20,7 @@ type port_id = int; struct chan_t { task: task_id, port: port_id, + marker: PhantomData<*mut T>, } fn send(_ch: chan_t, _data: T) { panic!(); } diff --git a/src/test/run-make/rustdoc-json/foo.rs b/src/test/run-make/rustdoc-json/foo.rs index d57a7164cdbce..3bd56c14193a8 100644 --- a/src/test/run-make/rustdoc-json/foo.rs +++ b/src/test/run-make/rustdoc-json/foo.rs @@ -21,5 +21,5 @@ pub mod bar { } /// *wow* - pub trait Doge { } + pub trait Doge { fn dummy(&self) { } } } diff --git a/src/test/run-make/rustdoc-negative-impl/foo.rs b/src/test/run-make/rustdoc-negative-impl/foo.rs index b5fcbf46c5c98..6c56bcc9be67b 100644 --- a/src/test/run-make/rustdoc-negative-impl/foo.rs +++ b/src/test/run-make/rustdoc-negative-impl/foo.rs @@ -13,7 +13,7 @@ // @matches foo/struct.Alpha.html '//pre' "pub struct Alpha" pub struct Alpha; // @matches foo/struct.Bravo.html '//pre' "pub struct Bravo" -pub struct Bravo; +pub struct Bravo(B); // @matches foo/struct.Alpha.html '//*[@class="impl"]//code' "impl !Send for Alpha" impl !Send for Alpha {} diff --git a/src/test/run-make/rustdoc-search-index/index.rs b/src/test/run-make/rustdoc-search-index/index.rs index dd68f2d6f1dee..42469a21f22d0 100644 --- a/src/test/run-make/rustdoc-search-index/index.rs +++ b/src/test/run-make/rustdoc-search-index/index.rs @@ -21,6 +21,6 @@ mod private { } pub trait PrivateTrait { - fn trait_method() {} // @!has - priv_method + fn trait_method(&self) {} // @!has - priv_method } } diff --git a/src/test/run-make/rustdoc-smoke/foo.rs b/src/test/run-make/rustdoc-smoke/foo.rs index 0438c9aba3599..f6b73021bebdf 100644 --- a/src/test/run-make/rustdoc-smoke/foo.rs +++ b/src/test/run-make/rustdoc-smoke/foo.rs @@ -26,7 +26,7 @@ pub mod bar { /// *wow* // @has foo/bar/trait.Doge.html - pub trait Doge { } + pub trait Doge { fn dummy(&self) { } } // @has foo/bar/struct.Foo.html pub struct Foo { x: int, y: uint } diff --git a/src/test/run-make/rustdoc-viewpath-self/foo.rs b/src/test/run-make/rustdoc-viewpath-self/foo.rs index da8f739302390..6fd47d84c30fe 100644 --- a/src/test/run-make/rustdoc-viewpath-self/foo.rs +++ b/src/test/run-make/rustdoc-viewpath-self/foo.rs @@ -9,7 +9,7 @@ // except according to those terms. pub mod io { - pub trait Reader { } + pub trait Reader { fn dummy(&self) { } } } pub enum Maybe { diff --git a/src/test/run-make/rustdoc-where/foo.rs b/src/test/run-make/rustdoc-where/foo.rs index 68fde60564e2a..91a7e1c9fd4ae 100644 --- a/src/test/run-make/rustdoc-where/foo.rs +++ b/src/test/run-make/rustdoc-where/foo.rs @@ -8,30 +8,33 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait MyTrait {} +pub trait MyTrait { fn dummy(&self) { } } // @has foo/struct.Alpha.html '//pre' "pub struct Alpha where A: MyTrait" -pub struct Alpha where A: MyTrait; +pub struct Alpha(A) where A: MyTrait; // @has foo/trait.Bravo.html '//pre' "pub trait Bravo where B: MyTrait" -pub trait Bravo where B: MyTrait {} +pub trait Bravo where B: MyTrait { fn get(&self, B: B); } // @has foo/fn.charlie.html '//pre' "pub fn charlie() where C: MyTrait" pub fn charlie() where C: MyTrait {} -pub struct Delta; +pub struct Delta(D); + // @has foo/struct.Delta.html '//*[@class="impl"]//code' \ // "impl Delta where D: MyTrait" impl Delta where D: MyTrait { pub fn delta() {} } -pub struct Echo; +pub struct Echo(E); + // @has foo/struct.Echo.html '//*[@class="impl"]//code' \ // "impl MyTrait for Echo where E: MyTrait" // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//code' \ // "impl MyTrait for Echo where E: MyTrait" impl MyTrait for Echo where E: MyTrait {} -pub enum Foxtrot {} +pub enum Foxtrot { Foxtrot1(F) } + // @has foo/enum.Foxtrot.html '//*[@class="impl"]//code' \ // "impl MyTrait for Foxtrot where F: MyTrait" // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//code' \ diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make/save-analysis/foo.rs index d90219b4221eb..ffadc57d1b08e 100644 --- a/src/test/run-make/save-analysis/foo.rs +++ b/src/test/run-make/save-analysis/foo.rs @@ -99,6 +99,7 @@ struct some_fields { type SF = some_fields; trait SuperTrait { + fn dummy(&self) { } } trait SomeTrait: SuperTrait { diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs index 834a2adf01fd3..f418d5d1fb74f 100755 --- a/src/test/run-make/simd-ffi/simd.rs +++ b/src/test/run-make/simd-ffi/simd.rs @@ -70,10 +70,14 @@ pub fn bar(a: i32x4, b: i32x4) -> i32x4 { } #[lang = "sized"] -trait Sized {} +pub trait Sized : PhantomFn {} #[lang = "copy"] -trait Copy {} +pub trait Copy : PhantomFn {} + +#[lang="phantom_fn"] +pub trait PhantomFn { } +impl PhantomFn for U { } mod core { pub mod marker { diff --git a/src/test/run-make/symbols-are-reasonable/lib.rs b/src/test/run-make/symbols-are-reasonable/lib.rs index 7cfebb31b2290..474a6782b616b 100644 --- a/src/test/run-make/symbols-are-reasonable/lib.rs +++ b/src/test/run-make/symbols-are-reasonable/lib.rs @@ -11,7 +11,7 @@ pub static X: &'static str = "foobarbaz"; pub static Y: &'static [u8] = include_bytes!("lib.rs"); -trait Foo {} +trait Foo { fn dummy(&self) { } } impl Foo for uint {} pub fn dummy() { diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs index 365fc039a4ec3..acda8705b19e3 100644 --- a/src/test/run-make/target-specs/foo.rs +++ b/src/test/run-make/target-specs/foo.rs @@ -11,11 +11,15 @@ #![feature(lang_items, no_std)] #![no_std] +#[lang="phantom_fn"] +trait PhantomFn { } +impl PhantomFn for U { } + #[lang="copy"] -trait Copy { } +trait Copy : PhantomFn { } #[lang="sized"] -trait Sized { } +trait Sized : PhantomFn { } #[lang="start"] fn start(_main: *const u8, _argc: int, _argv: *const *const u8) -> int { 0 } diff --git a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs index 195055f12d1e4..aecec44f6fd3d 100644 --- a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs +++ b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs @@ -25,7 +25,7 @@ impl Drop for Foo { } -trait Trait {} +trait Trait { fn dummy(&self) { } } impl Trait for Foo {} pub fn main() { diff --git a/src/test/run-pass-valgrind/dst-dtor-1.rs b/src/test/run-pass-valgrind/dst-dtor-1.rs index 47e2a18a9992a..c49a684de945d 100644 --- a/src/test/run-pass-valgrind/dst-dtor-1.rs +++ b/src/test/run-pass-valgrind/dst-dtor-1.rs @@ -19,7 +19,7 @@ impl Drop for Foo { } } -trait Trait {} +trait Trait { fn dummy(&self) { } } impl Trait for Foo {} struct Fat { diff --git a/src/test/run-pass/associated-types-basic.rs b/src/test/run-pass/associated-types-basic.rs index 3314b61320159..f5521f7da853b 100644 --- a/src/test/run-pass/associated-types-basic.rs +++ b/src/test/run-pass/associated-types-basic.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo { +use std::marker::MarkerTrait; + +trait Foo : MarkerTrait { type T; } diff --git a/src/test/run-pass/associated-types-conditional-dispatch.rs b/src/test/run-pass/associated-types-conditional-dispatch.rs index f21b7183d70c4..aa65b0ed10baf 100644 --- a/src/test/run-pass/associated-types-conditional-dispatch.rs +++ b/src/test/run-pass/associated-types-conditional-dispatch.rs @@ -14,6 +14,7 @@ // `Target=[A]`, then the impl marked with `(*)` is seen to conflict // with all the others. +use std::marker::PhantomData; use std::ops::Deref; pub trait MyEq { @@ -41,7 +42,8 @@ impl<'a, A, B, Lhs> MyEq<[B; 0]> for Lhs } struct DerefWithHelper { - pub helper: H + pub helper: H, + pub marker: PhantomData, } trait Helper { @@ -63,7 +65,8 @@ impl> Deref for DerefWithHelper { } pub fn check(x: T, y: T) -> bool { - let d: DerefWithHelper, T> = DerefWithHelper { helper: Some(x) }; + let d: DerefWithHelper, T> = DerefWithHelper { helper: Some(x), + marker: PhantomData }; d.eq(&y) } diff --git a/src/test/run-pass/associated-types-issue-20371.rs b/src/test/run-pass/associated-types-issue-20371.rs index d35b7331d4dbf..40ef7f3531cb5 100644 --- a/src/test/run-pass/associated-types-issue-20371.rs +++ b/src/test/run-pass/associated-types-issue-20371.rs @@ -11,6 +11,8 @@ // Test that we are able to have an impl that defines an associated type // before the actual trait. +use std::marker::MarkerTrait; + impl X for f64 { type Y = int; } -trait X {type Y; } +trait X : MarkerTrait { type Y; } fn main() {} diff --git a/src/test/run-pass/associated-types-issue-21212.rs b/src/test/run-pass/associated-types-issue-21212.rs index ced44250e4d39..3c91577362a7d 100644 --- a/src/test/run-pass/associated-types-issue-21212.rs +++ b/src/test/run-pass/associated-types-issue-21212.rs @@ -20,7 +20,8 @@ pub trait Parser { panic!() } } -impl

Parser for P { + +impl

(&self, n: uint, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { + fn splitn2

(&self, n: u32, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { SliceExt2::split2(self, pred); loop {} } diff --git a/src/test/run-pass/associated-types-normalize-in-bounds.rs b/src/test/run-pass/associated-types-normalize-in-bounds.rs index 742bab0578e9c..94cfcb8365381 100644 --- a/src/test/run-pass/associated-types-normalize-in-bounds.rs +++ b/src/test/run-pass/associated-types-normalize-in-bounds.rs @@ -11,15 +11,17 @@ // Test that we normalize associated types that appear in bounds; if // we didn't, the call to `self.split2()` fails to type check. -struct Splits<'a, T, P>; -struct SplitsN; +use std::marker::PhantomData; + +struct Splits<'a, T, P>(PhantomData<(&'a(),T,P)>); +struct SplitsN(PhantomData); trait SliceExt2 { type Item; fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P> where P: FnMut(&Self::Item) -> bool; - fn splitn2<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> + fn splitn2<'a, P>(&'a self, n: usize, pred: P) -> SplitsN> where P: FnMut(&Self::Item) -> bool; } @@ -30,7 +32,7 @@ impl SliceExt2 for [T] { loop {} } - fn splitn2

(&self, n: uint, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { + fn splitn2

(&self, n: usize, pred: P) -> SplitsN> where P: FnMut(&T) -> bool { self.split2(pred); loop {} } diff --git a/src/test/run-pass/associated-types-normalize-unifield-struct.rs b/src/test/run-pass/associated-types-normalize-unifield-struct.rs index 5aafe93067c13..2288e19aae0bc 100644 --- a/src/test/run-pass/associated-types-normalize-unifield-struct.rs +++ b/src/test/run-pass/associated-types-normalize-unifield-struct.rs @@ -13,7 +13,10 @@ pub trait OffsetState: Sized {} -pub trait Offset { type State: OffsetState; } +pub trait Offset { + type State: OffsetState; + fn dummy(&self) { } +} #[derive(Copy)] pub struct X; impl Offset for X { type State = Y; } diff --git a/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs b/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs index 0a1a8589dec82..c65d2db9b0cf0 100644 --- a/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs +++ b/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs @@ -13,6 +13,8 @@ trait Int { type T; + + fn dummy(&self) { } } trait NonZero diff --git a/src/test/run-pass/associated-types-projection-in-object-type.rs b/src/test/run-pass/associated-types-projection-in-object-type.rs index 44dd49b72976e..a9c34a605ce16 100644 --- a/src/test/run-pass/associated-types-projection-in-object-type.rs +++ b/src/test/run-pass/associated-types-projection-in-object-type.rs @@ -18,6 +18,8 @@ use std::cell::RefCell; pub trait Subscriber { type Input; + + fn dummy(&self) { } } pub trait Publisher<'a> { diff --git a/src/test/run-pass/associated-types-projection-in-supertrait.rs b/src/test/run-pass/associated-types-projection-in-supertrait.rs index e6fec675b0363..4d2358fae27b1 100644 --- a/src/test/run-pass/associated-types-projection-in-supertrait.rs +++ b/src/test/run-pass/associated-types-projection-in-supertrait.rs @@ -14,6 +14,8 @@ trait A { type TA; + + fn dummy(&self) { } } trait B diff --git a/src/test/run-pass/associated-types-projection-in-where-clause.rs b/src/test/run-pass/associated-types-projection-in-where-clause.rs index 10a459f3c3662..3f3f4fbd1d628 100644 --- a/src/test/run-pass/associated-types-projection-in-where-clause.rs +++ b/src/test/run-pass/associated-types-projection-in-where-clause.rs @@ -13,6 +13,8 @@ trait Int { type T; + + fn dummy(&self) { } } trait NonZero diff --git a/src/test/run-pass/associated-types-ref-in-struct-literal.rs b/src/test/run-pass/associated-types-ref-in-struct-literal.rs index 022c8f4cd0130..67fe11d8fedde 100644 --- a/src/test/run-pass/associated-types-ref-in-struct-literal.rs +++ b/src/test/run-pass/associated-types-ref-in-struct-literal.rs @@ -12,6 +12,8 @@ pub trait Foo { type Bar; + + fn dummy(&self) { } } impl Foo for int { diff --git a/src/test/run-pass/associated-types-resolve-lifetime.rs b/src/test/run-pass/associated-types-resolve-lifetime.rs index e7a8061a3467a..a4b0b1a6e03af 100644 --- a/src/test/run-pass/associated-types-resolve-lifetime.rs +++ b/src/test/run-pass/associated-types-resolve-lifetime.rs @@ -15,6 +15,8 @@ trait Get { trait Trait<'a> { type T: 'static; type U: Get<&'a int>; + + fn dummy(&'a self) { } } fn main() {} diff --git a/src/test/run-pass/associated-types-struct-field-named.rs b/src/test/run-pass/associated-types-struct-field-named.rs index 1ded34ff3ffe3..8667f6c8430ab 100644 --- a/src/test/run-pass/associated-types-struct-field-named.rs +++ b/src/test/run-pass/associated-types-struct-field-named.rs @@ -13,6 +13,8 @@ pub trait UnifyKey { type Value; + + fn dummy(&self) { } } pub struct Node { diff --git a/src/test/run-pass/associated-types-struct-field-numbered.rs b/src/test/run-pass/associated-types-struct-field-numbered.rs index 3669dec4fbdd4..9503f78a71b90 100644 --- a/src/test/run-pass/associated-types-struct-field-numbered.rs +++ b/src/test/run-pass/associated-types-struct-field-numbered.rs @@ -13,6 +13,8 @@ pub trait UnifyKey { type Value; + + fn dummy(&self) { } } pub struct Node(K, K::Value); diff --git a/src/test/run-pass/associated-types-sugar-path.rs b/src/test/run-pass/associated-types-sugar-path.rs index ea1df6658fd05..b1878fa3558d6 100644 --- a/src/test/run-pass/associated-types-sugar-path.rs +++ b/src/test/run-pass/associated-types-sugar-path.rs @@ -31,8 +31,9 @@ pub fn bar(a: T, x: T::A) -> T::A { // Using a type via an impl. trait C { fn f(); + fn g(&self) { } } -struct B; +struct B(X); impl C for B { fn f() { let x: T::A = panic!(); diff --git a/src/test/run-pass/borrowck-trait-lifetime.rs b/src/test/run-pass/borrowck-trait-lifetime.rs index b39f03a93c9fe..be0c88f557cc7 100644 --- a/src/test/run-pass/borrowck-trait-lifetime.rs +++ b/src/test/run-pass/borrowck-trait-lifetime.rs @@ -12,8 +12,11 @@ // to the same lifetime on a trait succeeds. See issue #10766. #![allow(dead_code)] + +use std::marker; + fn main() { - trait T {} + trait T : marker::MarkerTrait {} fn f<'a, V: T>(v: &'a V) -> &'a T { v as &'a T diff --git a/src/test/run-pass/bug-7295.rs b/src/test/run-pass/bug-7295.rs index ea711d78dd28e..143ebfdabface 100644 --- a/src/test/run-pass/bug-7295.rs +++ b/src/test/run-pass/bug-7295.rs @@ -9,10 +9,10 @@ // except according to those terms. pub trait Foo { - fn func1(&self, t: U); + fn func1(&self, t: U, w: T); - fn func2(&self, t: U) { - self.func1(t); + fn func2(&self, t: U, w: T) { + self.func1(t, w); } } diff --git a/src/test/run-pass/builtin-superkinds-in-metadata.rs b/src/test/run-pass/builtin-superkinds-in-metadata.rs index c115415bb9b7b..7eaed910124d9 100644 --- a/src/test/run-pass/builtin-superkinds-in-metadata.rs +++ b/src/test/run-pass/builtin-superkinds-in-metadata.rs @@ -16,6 +16,7 @@ extern crate trait_superkinds_in_metadata; use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare}; use trait_superkinds_in_metadata::{RequiresCopy}; +use std::marker; #[derive(Copy)] struct X(T); diff --git a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs index 7e1b28219373b..964c28dc94517 100644 --- a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs +++ b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs @@ -12,10 +12,12 @@ // super-builtin-kind of a trait, if the type parameter is never used, // the type can implement the trait anyway. +use std::marker; + trait Foo : Send { } -struct X(()); +struct X { marker: marker::PhantomData } -impl Foo for X { } +impl Foo for X { } pub fn main() { } diff --git a/src/test/run-pass/class-typarams.rs b/src/test/run-pass/class-typarams.rs index 9d4e73da81304..15e98519fbcd6 100644 --- a/src/test/run-pass/class-typarams.rs +++ b/src/test/run-pass/class-typarams.rs @@ -8,10 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker::PhantomData; + struct cat { meows : uint, - how_hungry : int, + m: PhantomData } impl cat { @@ -22,7 +24,8 @@ impl cat { fn cat(in_x : uint, in_y : int) -> cat { cat { meows: in_x, - how_hungry: in_y + how_hungry: in_y, + m: PhantomData } } diff --git a/src/test/run-pass/dst-coercions.rs b/src/test/run-pass/dst-coercions.rs index dbad546ce1ae3..30ed0b8e40245 100644 --- a/src/test/run-pass/dst-coercions.rs +++ b/src/test/run-pass/dst-coercions.rs @@ -11,7 +11,7 @@ // Test coercions involving DST and/or raw pointers struct S; -trait T {} +trait T { fn dummy(&self) { } } impl T for S {} pub fn main() { diff --git a/src/test/run-pass/enum-null-pointer-opt.rs b/src/test/run-pass/enum-null-pointer-opt.rs index 797c26556aaa1..023376ce4736e 100644 --- a/src/test/run-pass/enum-null-pointer-opt.rs +++ b/src/test/run-pass/enum-null-pointer-opt.rs @@ -16,7 +16,7 @@ use std::mem::size_of; use std::rc::Rc; use std::sync::Arc; -trait Trait {} +trait Trait { fn dummy(&self) { } } fn main() { // Functions diff --git a/src/test/run-pass/explicit-self-generic.rs b/src/test/run-pass/explicit-self-generic.rs index 066a5f9580ac4..382c5c58e92ee 100644 --- a/src/test/run-pass/explicit-self-generic.rs +++ b/src/test/run-pass/explicit-self-generic.rs @@ -15,21 +15,19 @@ struct LM { resize_at: uint, size: uint } enum HashMap { - HashMap_(LM) + HashMap_(LM, Vec<(K,V)>) } -impl Copy for HashMap {} - fn linear_map() -> HashMap { HashMap::HashMap_(LM{ resize_at: 32, - size: 0}) + size: 0}, Vec::new()) } impl HashMap { pub fn len(&mut self) -> uint { match *self { - HashMap::HashMap_(l) => l.size + HashMap::HashMap_(ref l, _) => l.size } } } diff --git a/src/test/run-pass/export-non-interference.rs b/src/test/run-pass/export-non-interference.rs deleted file mode 100644 index 94652e30fe64f..0000000000000 --- a/src/test/run-pass/export-non-interference.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2012 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. - - -enum list_cell { cons(Box>), nil } - -pub fn main() { } diff --git a/src/test/run-pass/generic-default-type-params-cross-crate.rs b/src/test/run-pass/generic-default-type-params-cross-crate.rs index ed8c6e73255bb..bf02b82d1a075 100644 --- a/src/test/run-pass/generic-default-type-params-cross-crate.rs +++ b/src/test/run-pass/generic-default-type-params-cross-crate.rs @@ -12,13 +12,13 @@ extern crate default_type_params_xc; -struct Vec; +struct Vec(Option<(T,A)>); struct Foo; fn main() { - let _a = Vec::; - let _b = Vec::; - let _c = default_type_params_xc::FakeVec::; - let _d = default_type_params_xc::FakeVec::; + let _a = Vec::(None); + let _b = Vec::(None); + let _c = default_type_params_xc::FakeVec:: { f: None }; + let _d = default_type_params_xc::FakeVec:: { f: None }; } diff --git a/src/test/run-pass/hrtb-opt-in-copy.rs b/src/test/run-pass/hrtb-opt-in-copy.rs index 9c9f95f61e9be..7b16bb867e79c 100644 --- a/src/test/run-pass/hrtb-opt-in-copy.rs +++ b/src/test/run-pass/hrtb-opt-in-copy.rs @@ -18,7 +18,7 @@ #![allow(dead_code)] -use std::marker; +use std::marker::PhantomData; #[derive(Copy)] struct Foo { x: T } @@ -26,7 +26,7 @@ struct Foo { x: T } type Ty<'tcx> = &'tcx TyS<'tcx>; enum TyS<'tcx> { - Boop(marker::InvariantLifetime<'tcx>) + Boop(PhantomData<*mut &'tcx ()>) } #[derive(Copy)] diff --git a/src/test/run-pass/inner-static.rs b/src/test/run-pass/inner-static.rs index f9b430c1553dd..e4026a8fd0118 100644 --- a/src/test/run-pass/inner-static.rs +++ b/src/test/run-pass/inner-static.rs @@ -13,9 +13,9 @@ extern crate inner_static; pub fn main() { - let a = inner_static::A::<()>; - let b = inner_static::B::<()>; - let c = inner_static::test::A::<()>; + let a = inner_static::A::<()> { v: () }; + let b = inner_static::B::<()> { v: () }; + let c = inner_static::test::A::<()> { v: () }; assert_eq!(a.bar(), 2); assert_eq!(b.bar(), 4); assert_eq!(c.bar(), 6); diff --git a/src/test/run-pass/issue-10456.rs b/src/test/run-pass/issue-10456.rs index b714d87f4ef20..da73c4b27ac44 100644 --- a/src/test/run-pass/issue-10456.rs +++ b/src/test/run-pass/issue-10456.rs @@ -14,7 +14,9 @@ pub trait Bar { fn bar(&self); } -pub trait Baz {} +pub trait Baz { + fn baz(&self) { } +} impl Bar for T { fn bar(&self) {} diff --git a/src/test/run-pass/issue-10802.rs b/src/test/run-pass/issue-10802.rs index de2b4c51e52a9..174a69e1135cd 100644 --- a/src/test/run-pass/issue-10802.rs +++ b/src/test/run-pass/issue-10802.rs @@ -29,7 +29,7 @@ impl Drop for DroppableEnum { } } -trait MyTrait { } +trait MyTrait { fn dummy(&self) { } } impl MyTrait for Box {} impl MyTrait for Box {} diff --git a/src/test/run-pass/issue-10902.rs b/src/test/run-pass/issue-10902.rs index 324a1701b2feb..7fab6662ee01c 100644 --- a/src/test/run-pass/issue-10902.rs +++ b/src/test/run-pass/issue-10902.rs @@ -9,7 +9,7 @@ // except according to those terms. pub mod two_tuple { - pub trait T {} + pub trait T { fn dummy(&self) { } } pub struct P<'a>(&'a (T + 'a), &'a (T + 'a)); pub fn f<'a>(car: &'a T, cdr: &'a T) -> P<'a> { P(car, cdr) @@ -17,7 +17,7 @@ pub mod two_tuple { } pub mod two_fields { - pub trait T {} + pub trait T { fn dummy(&self) { } } pub struct P<'a> { car: &'a (T + 'a), cdr: &'a (T + 'a) } pub fn f<'a>(car: &'a T, cdr: &'a T) -> P<'a> { P{ car: car, cdr: cdr } diff --git a/src/test/run-pass/issue-11205.rs b/src/test/run-pass/issue-11205.rs index d7c6c1b1bb2c2..1325b51a54ff2 100644 --- a/src/test/run-pass/issue-11205.rs +++ b/src/test/run-pass/issue-11205.rs @@ -12,7 +12,7 @@ #![allow(unknown_features)] #![feature(box_syntax)] -trait Foo {} +trait Foo { fn dummy(&self) { } } impl Foo for int {} fn foo(_: [&Foo; 2]) {} fn foos(_: &[&Foo]) {} diff --git a/src/test/run-pass/issue-11384.rs b/src/test/run-pass/issue-11384.rs index a511149b05e2a..26634fabf5a15 100644 --- a/src/test/run-pass/issue-11384.rs +++ b/src/test/run-pass/issue-11384.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Common {} +trait Common { fn dummy(&self) { } } impl<'t, T> Common for (T, &'t T) {} diff --git a/src/test/run-pass/issue-11612.rs b/src/test/run-pass/issue-11612.rs index fa25d25df054e..3c69377b375c6 100644 --- a/src/test/run-pass/issue-11612.rs +++ b/src/test/run-pass/issue-11612.rs @@ -12,7 +12,7 @@ // We weren't updating the auto adjustments with all the resolved // type information after type check. -trait A {} +trait A { fn dummy(&self) { } } struct B<'a, T:'a> { f: &'a T diff --git a/src/test/run-pass/issue-11677.rs b/src/test/run-pass/issue-11677.rs index 6fa4505869478..7cccac4483d49 100644 --- a/src/test/run-pass/issue-11677.rs +++ b/src/test/run-pass/issue-11677.rs @@ -14,13 +14,18 @@ // this code used to cause an ICE -trait X {} +use std::marker; + +trait X { + fn dummy(&self) -> T { panic!() } +} struct S {f: Box+'static>, g: Box+'static>} struct F; -impl X for F {} +impl X for F { +} fn main() { S {f: box F, g: box F}; diff --git a/src/test/run-pass/issue-13105.rs b/src/test/run-pass/issue-13105.rs index 7fab36bd64ec7..64807dc44e061 100644 --- a/src/test/run-pass/issue-13105.rs +++ b/src/test/run-pass/issue-13105.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo { +use std::marker::MarkerTrait; + +trait Foo : MarkerTrait { fn quux(u8) {} } diff --git a/src/test/run-pass/issue-14399.rs b/src/test/run-pass/issue-14399.rs index 7e533c2cf86c1..4f3db1352bbd2 100644 --- a/src/test/run-pass/issue-14399.rs +++ b/src/test/run-pass/issue-14399.rs @@ -19,7 +19,7 @@ #[derive(Clone)] struct B1; -trait A {} +trait A : std::marker::MarkerTrait {} impl A for B1 {} fn main() { diff --git a/src/test/run-pass/issue-14589.rs b/src/test/run-pass/issue-14589.rs index d9763baa82657..71d88ee621510 100644 --- a/src/test/run-pass/issue-14589.rs +++ b/src/test/run-pass/issue-14589.rs @@ -17,17 +17,18 @@ fn main() { send::>(box Output(0)); Test::>::foo(box Output(0)); - Test::>.send(box Output(0)); + Test::>::new().send(box Output(0)); } fn send(_: T) {} -struct Test; +struct Test { marker: std::marker::PhantomData } impl Test { + fn new() -> Test { Test { marker: ::std::marker::PhantomData } } fn foo(_: T) {} fn send(&self, _: T) {} } -trait Foo {} +trait Foo { fn dummy(&self) { }} struct Output(int); impl Foo for Output {} diff --git a/src/test/run-pass/issue-14958.rs b/src/test/run-pass/issue-14958.rs index 814a743648d3f..6335f79be6c7a 100644 --- a/src/test/run-pass/issue-14958.rs +++ b/src/test/run-pass/issue-14958.rs @@ -10,7 +10,7 @@ #![feature(unboxed_closures)] -trait Foo {} +trait Foo { fn dummy(&self) { }} struct Bar; diff --git a/src/test/run-pass/issue-14959.rs b/src/test/run-pass/issue-14959.rs index 33281d7d78ffb..53d0f7dae0577 100644 --- a/src/test/run-pass/issue-14959.rs +++ b/src/test/run-pass/issue-14959.rs @@ -12,8 +12,8 @@ use std::ops::Fn; -trait Response {} -trait Request {} +trait Response { fn dummy(&self) { } } +trait Request { fn dummy(&self) { } } trait Ingot { fn enter(&mut self, _: &mut R, _: &mut S, a: &mut Alloy) -> Status; } @@ -21,7 +21,7 @@ trait Ingot { #[allow(dead_code)] struct HelloWorld; -struct SendFile<'a>; +struct SendFile; struct Alloy; enum Status { Continue @@ -33,7 +33,7 @@ impl Alloy { } } -impl<'a, 'b> Fn<(&'b mut (Response+'b),)> for SendFile<'a> { +impl<'b> Fn<(&'b mut (Response+'b),)> for SendFile { type Output = (); extern "rust-call" fn call(&self, (_res,): (&'b mut (Response+'b),)) {} diff --git a/src/test/run-pass/issue-15858.rs b/src/test/run-pass/issue-15858.rs index c75c672546125..6a4f78442d149 100644 --- a/src/test/run-pass/issue-15858.rs +++ b/src/test/run-pass/issue-15858.rs @@ -12,21 +12,21 @@ static mut DROP_RAN: bool = false; -trait Bar<'b> { +trait Bar { fn do_something(&mut self); } -struct BarImpl<'b>; +struct BarImpl; -impl<'b> Bar<'b> for BarImpl<'b> { +impl Bar for BarImpl { fn do_something(&mut self) {} } -struct Foo; +struct Foo(B); #[unsafe_destructor] -impl<'b, B: Bar<'b>> Drop for Foo { +impl Drop for Foo { fn drop(&mut self) { unsafe { DROP_RAN = true; @@ -37,7 +37,7 @@ impl<'b, B: Bar<'b>> Drop for Foo { fn main() { { - let _x: Foo = Foo; + let _x: Foo = Foo(BarImpl); } unsafe { assert_eq!(DROP_RAN, true); diff --git a/src/test/run-pass/issue-16596.rs b/src/test/run-pass/issue-16596.rs index e01de3a3262ed..1ba7b142e5e15 100644 --- a/src/test/run-pass/issue-16596.rs +++ b/src/test/run-pass/issue-16596.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait MatrixRow {} +trait MatrixRow { fn dummy(&self) { }} struct Mat; diff --git a/src/test/run-pass/issue-16643.rs b/src/test/run-pass/issue-16643.rs index b118c9573cdcf..4e57c55c5f755 100644 --- a/src/test/run-pass/issue-16643.rs +++ b/src/test/run-pass/issue-16643.rs @@ -13,5 +13,5 @@ extern crate "issue-16643" as i; pub fn main() { - i::TreeBuilder::.process_token(); + i::TreeBuilder { h: 3u }.process_token(); } diff --git a/src/test/run-pass/issue-17662.rs b/src/test/run-pass/issue-17662.rs index 34bcfeb10dec3..196c148f19331 100644 --- a/src/test/run-pass/issue-17662.rs +++ b/src/test/run-pass/issue-17662.rs @@ -12,12 +12,14 @@ extern crate "issue-17662" as i; -struct Bar<'a>; +use std::marker; + +struct Bar<'a> { m: marker::PhantomData<&'a ()> } impl<'a> i::Foo<'a, uint> for Bar<'a> { fn foo(&self) -> uint { 5u } } pub fn main() { - assert_eq!(i::foo(&Bar), 5); + assert_eq!(i::foo(&Bar { m: marker::PhantomData }), 5); } diff --git a/src/test/run-pass/issue-17732.rs b/src/test/run-pass/issue-17732.rs index b4bd55da59757..de9611f259227 100644 --- a/src/test/run-pass/issue-17732.rs +++ b/src/test/run-pass/issue-17732.rs @@ -10,8 +10,9 @@ trait Person { type string; + fn dummy(&self) { } } -struct Someone; +struct Someone(std::marker::PhantomData

); fn main() {} diff --git a/src/test/run-pass/issue-17771.rs b/src/test/run-pass/issue-17771.rs index 1e9550acef4cb..2f1b0342b8e04 100644 --- a/src/test/run-pass/issue-17771.rs +++ b/src/test/run-pass/issue-17771.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Aaa {} +trait Aaa { fn dummy(&self) { } } impl<'a> Aaa for &'a mut (Aaa + 'a) {} diff --git a/src/test/run-pass/issue-17816.rs b/src/test/run-pass/issue-17816.rs index f8fbd680dcb9e..a976eccf89ec4 100644 --- a/src/test/run-pass/issue-17816.rs +++ b/src/test/run-pass/issue-17816.rs @@ -10,9 +10,11 @@ #![feature(unboxed_closures)] +use std::marker::PhantomData; + fn main() { - struct Symbol<'a, F: Fn(Vec<&'a str>) -> &'a str> { function: F } + struct Symbol<'a, F: Fn(Vec<&'a str>) -> &'a str> { function: F, marker: PhantomData<&'a ()> } let f = |x: Vec<&str>| -> &str "foobar"; - let sym = Symbol { function: f }; + let sym = Symbol { function: f, marker: PhantomData }; (sym.function)(vec![]); } diff --git a/src/test/run-pass/issue-17904.rs b/src/test/run-pass/issue-17904.rs index 3ce347d67e3d9..58a0872a5719b 100644 --- a/src/test/run-pass/issue-17904.rs +++ b/src/test/run-pass/issue-17904.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Foo where T: Copy; +// Test that we can parse where clauses on various forms of tuple +// structs. + struct Bar(T) where T: Copy; struct Bleh(T, U) where T: Copy, U: Sized; struct Baz where T: Copy { diff --git a/src/test/run-pass/issue-18232.rs b/src/test/run-pass/issue-18232.rs index 15cf5870d40ad..67b3239d35197 100644 --- a/src/test/run-pass/issue-18232.rs +++ b/src/test/run-pass/issue-18232.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Cursor<'a>; +struct Cursor<'a>(::std::marker::PhantomData<&'a ()>); trait CursorNavigator { fn init_cursor<'a, 'b:'a>(&'a self, cursor: &mut Cursor<'b>) -> bool; @@ -23,7 +23,7 @@ impl CursorNavigator for SimpleNavigator { } fn main() { - let mut c = Cursor; + let mut c = Cursor(::std::marker::PhantomData); let n = SimpleNavigator; n.init_cursor(&mut c); } diff --git a/src/test/run-pass/issue-18906.rs b/src/test/run-pass/issue-18906.rs index 11ffb4198dad8..16dd84315ed2c 100644 --- a/src/test/run-pass/issue-18906.rs +++ b/src/test/run-pass/issue-18906.rs @@ -24,7 +24,7 @@ fn bar(k: &K, q: &Q) where K: Borrow, Q: Foo { q.foo(k.borrow()) } -struct MyTree; +struct MyTree(K); impl MyTree { // This caused a failure in #18906 diff --git a/src/test/run-pass/issue-19121.rs b/src/test/run-pass/issue-19121.rs index d95f74ef2a2ba..222f67af437ef 100644 --- a/src/test/run-pass/issue-19121.rs +++ b/src/test/run-pass/issue-19121.rs @@ -13,6 +13,8 @@ trait Foo { type A; + + fn dummy(&self) { } } fn bar(x: &Foo) {} diff --git a/src/test/run-pass/issue-19129-2.rs b/src/test/run-pass/issue-19129-2.rs index d6b3a1908b82d..cf0f48e025a0e 100644 --- a/src/test/run-pass/issue-19129-2.rs +++ b/src/test/run-pass/issue-19129-2.rs @@ -11,7 +11,7 @@ trait Trait { type Output; - fn method() -> bool { false } + fn method(&self, i: Input) -> bool { false } } fn main() {} diff --git a/src/test/run-pass/issue-19135.rs b/src/test/run-pass/issue-19135.rs index 031a63ba474c1..5e6dd567d6328 100644 --- a/src/test/run-pass/issue-19135.rs +++ b/src/test/run-pass/issue-19135.rs @@ -10,13 +10,15 @@ #![feature(unboxed_closures)] +use std::marker::PhantomData; + #[derive(Debug)] -struct LifetimeStruct<'a>; +struct LifetimeStruct<'a>(PhantomData<&'a ()>); fn main() { takes_hrtb_closure(|lts| println!("{:?}", lts)); } fn takes_hrtb_closureFnMut(LifetimeStruct<'a>)>(mut f: F) { - f(LifetimeStruct); + f(LifetimeStruct(PhantomData)); } diff --git a/src/test/run-pass/issue-19358.rs b/src/test/run-pass/issue-19358.rs index ff657376ecc1f..8b5269ab92f03 100644 --- a/src/test/run-pass/issue-19358.rs +++ b/src/test/run-pass/issue-19358.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Trait {} +trait Trait { fn dummy(&self) { } } #[derive(Debug)] struct Foo { diff --git a/src/test/run-pass/issue-19398.rs b/src/test/run-pass/issue-19398.rs index 1196162568a91..e603167b26be0 100644 --- a/src/test/run-pass/issue-19398.rs +++ b/src/test/run-pass/issue-19398.rs @@ -9,11 +9,11 @@ // except according to those terms. trait T { - unsafe extern "Rust" fn foo(); + unsafe extern "Rust" fn foo(&self); } impl T for () { - unsafe extern "Rust" fn foo() {} + unsafe extern "Rust" fn foo(&self) {} } fn main() {} diff --git a/src/test/run-pass/issue-19479.rs b/src/test/run-pass/issue-19479.rs index 91bc645b2d486..38a7af3a69597 100644 --- a/src/test/run-pass/issue-19479.rs +++ b/src/test/run-pass/issue-19479.rs @@ -8,12 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Base {} +trait Base { + fn dummy(&self) { } +} trait AssocA { type X: Base; + fn dummy(&self) { } } trait AssocB { type Y: Base; + fn dummy(&self) { } } impl AssocB for T { type Y = ::X; diff --git a/src/test/run-pass/issue-19631.rs b/src/test/run-pass/issue-19631.rs index 43116f63641de..7bb0d055b844d 100644 --- a/src/test/run-pass/issue-19631.rs +++ b/src/test/run-pass/issue-19631.rs @@ -10,6 +10,7 @@ trait PoolManager { type C; + fn dummy(&self) { } } struct InnerPool { diff --git a/src/test/run-pass/issue-19632.rs b/src/test/run-pass/issue-19632.rs index 01a073a6889ae..4339339d74c88 100644 --- a/src/test/run-pass/issue-19632.rs +++ b/src/test/run-pass/issue-19632.rs @@ -10,6 +10,7 @@ trait PoolManager { type C; + fn dummy(&self) { } } struct InnerPool { diff --git a/src/test/run-pass/issue-20055-box-trait.rs b/src/test/run-pass/issue-20055-box-trait.rs index 836e78b5b5143..572a0d825282e 100644 --- a/src/test/run-pass/issue-20055-box-trait.rs +++ b/src/test/run-pass/issue-20055-box-trait.rs @@ -16,7 +16,9 @@ // whichever arm is run, and subsequently dropped at the end of the // statement surrounding the `match`. -trait Boo { } +trait Boo { + fn dummy(&self) { } +} impl Boo for [i8; 1] { } impl Boo for [i8; 2] { } diff --git a/src/test/run-pass/issue-20343.rs b/src/test/run-pass/issue-20343.rs index 79034a4a4a6d6..2f9e8feed2482 100644 --- a/src/test/run-pass/issue-20343.rs +++ b/src/test/run-pass/issue-20343.rs @@ -16,7 +16,7 @@ struct B { b: u32 } struct C; struct D; -trait T {} +trait T { fn dummy(&self, a: A) { } } impl T for () {} impl B { diff --git a/src/test/run-pass/issue-20763-1.rs b/src/test/run-pass/issue-20763-1.rs index 911ee715da281..97c06ac98265f 100644 --- a/src/test/run-pass/issue-20763-1.rs +++ b/src/test/run-pass/issue-20763-1.rs @@ -8,7 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait T0 { type O; } +trait T0 { + type O; + fn dummy(&self) { } +} struct S(A); impl T0 for S { type O = A; } diff --git a/src/test/run-pass/issue-20763-2.rs b/src/test/run-pass/issue-20763-2.rs index a17c7b6ade48e..d97017635718c 100644 --- a/src/test/run-pass/issue-20763-2.rs +++ b/src/test/run-pass/issue-20763-2.rs @@ -8,7 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait T0 { type O; } +trait T0 { + type O; + fn dummy(&self) { } +} struct S(A); impl T0 for S { type O = A; } diff --git a/src/test/run-pass/issue-21363.rs b/src/test/run-pass/issue-21363.rs index 2fc1d9fd6433c..71bb3d39fe1d6 100644 --- a/src/test/run-pass/issue-21363.rs +++ b/src/test/run-pass/issue-21363.rs @@ -12,6 +12,7 @@ trait Iterator { type Item; + fn dummy(&self) { } } impl<'a, T> Iterator for &'a mut (Iterator + 'a) { diff --git a/src/test/run-pass/issue-21909.rs b/src/test/run-pass/issue-21909.rs index 5bbc90b260639..55b61dd194556 100644 --- a/src/test/run-pass/issue-21909.rs +++ b/src/test/run-pass/issue-21909.rs @@ -8,11 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait A {} +trait A { + fn dummy(&self, arg: X); +} trait B { type X; type Y: A; + + fn dummy(&self); } fn main () { } diff --git a/src/test/run-pass/issue-2311-2.rs b/src/test/run-pass/issue-2311-2.rs index e0b98ab19652a..5529d51b408c0 100644 --- a/src/test/run-pass/issue-2311-2.rs +++ b/src/test/run-pass/issue-2311-2.rs @@ -8,7 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait clam { } +trait clam { + fn get(self) -> A; +} + struct foo { x: A, } diff --git a/src/test/run-pass/issue-2311.rs b/src/test/run-pass/issue-2311.rs index dc873ed08d701..b6b3114e2a487 100644 --- a/src/test/run-pass/issue-2311.rs +++ b/src/test/run-pass/issue-2311.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait clam { } +trait clam { fn get(self) -> A; } trait foo { fn bar>(&self, c: C) -> B; } diff --git a/src/test/run-pass/issue-2312.rs b/src/test/run-pass/issue-2312.rs index 8c597552d75aa..3f273b56efd6c 100644 --- a/src/test/run-pass/issue-2312.rs +++ b/src/test/run-pass/issue-2312.rs @@ -10,7 +10,7 @@ // Testing that the B's are resolved -trait clam { } +trait clam { fn get(self) -> A; } struct foo(int); diff --git a/src/test/run-pass/issue-2611-3.rs b/src/test/run-pass/issue-2611-3.rs index 2608c89d15567..c005699ce30b4 100644 --- a/src/test/run-pass/issue-2611-3.rs +++ b/src/test/run-pass/issue-2611-3.rs @@ -12,7 +12,7 @@ // than the traits require. trait A { - fn b(x: C) -> C; + fn b(&self, x: C) -> C; } struct E { @@ -20,7 +20,7 @@ struct E { } impl A for E { - fn b(_x: F) -> F { panic!() } + fn b(&self, _x: F) -> F { panic!() } //~^ ERROR in method `b`, type parameter 0 has 1 bound, but } diff --git a/src/test/run-pass/issue-2734.rs b/src/test/run-pass/issue-2734.rs index 7ca439a1a19df..a7b53db6b0553 100644 --- a/src/test/run-pass/issue-2734.rs +++ b/src/test/run-pass/issue-2734.rs @@ -11,7 +11,9 @@ #![allow(unknown_features)] #![feature(box_syntax)] -trait hax { } +trait hax { + fn dummy(&self) { } +} impl hax for A { } fn perform_hax(x: Box) -> Box { diff --git a/src/test/run-pass/issue-2735.rs b/src/test/run-pass/issue-2735.rs index 962359537bf29..1594b94879cee 100644 --- a/src/test/run-pass/issue-2735.rs +++ b/src/test/run-pass/issue-2735.rs @@ -11,7 +11,9 @@ #![allow(unknown_features)] #![feature(box_syntax)] -trait hax { } +trait hax { + fn dummy(&self) { } +} impl hax for A { } fn perform_hax(x: Box) -> Box { diff --git a/src/test/run-pass/issue-4107.rs b/src/test/run-pass/issue-4107.rs index 2ed662e9f2d60..d660f300ada99 100644 --- a/src/test/run-pass/issue-4107.rs +++ b/src/test/run-pass/issue-4107.rs @@ -9,14 +9,14 @@ // except according to those terms. pub fn main() { - let _id: &Mat2 = &Matrix::identity(); + let _id: &Mat2 = &Matrix::identity(1.0); } -pub trait Index { } +pub trait Index { fn get(&self, Index) -> Result { panic!() } } pub trait Dimensional: Index { } -pub struct Mat2 { x: () } -pub struct Vec2 { x: () } +pub struct Mat2 { x: T } +pub struct Vec2 { x: T } impl Dimensional> for Mat2 { } impl Index> for Mat2 { } @@ -25,9 +25,9 @@ impl Dimensional for Vec2 { } impl Index for Vec2 { } pub trait Matrix: Dimensional { - fn identity() -> Self; + fn identity(t:T) -> Self; } impl Matrix> for Mat2 { - fn identity() -> Mat2 { Mat2{ x: () } } + fn identity(t:T) -> Mat2 { Mat2{ x: t } } } diff --git a/src/test/run-pass/issue-5192.rs b/src/test/run-pass/issue-5192.rs index bb79cd4d04667..a6f3771bf62b4 100644 --- a/src/test/run-pass/issue-5192.rs +++ b/src/test/run-pass/issue-5192.rs @@ -12,6 +12,7 @@ #![feature(box_syntax)] pub trait EventLoop { + fn dummy(&self) { } } pub struct UvEventLoop { diff --git a/src/test/run-pass/issue-5708.rs b/src/test/run-pass/issue-5708.rs index fd39bcc6b6121..59bca87bed0b6 100644 --- a/src/test/run-pass/issue-5708.rs +++ b/src/test/run-pass/issue-5708.rs @@ -48,7 +48,9 @@ pub fn main() { // minimal -pub trait MyTrait { } +pub trait MyTrait { + fn dummy(&self, t: T) -> T { panic!() } +} pub struct MyContainer<'a, T> { foos: Vec<&'a (MyTrait+'a)> , diff --git a/src/test/run-pass/issue-6128.rs b/src/test/run-pass/issue-6128.rs index d96862b588f9d..1746a6281dc26 100644 --- a/src/test/run-pass/issue-6128.rs +++ b/src/test/run-pass/issue-6128.rs @@ -17,6 +17,7 @@ use std::collections::HashMap; trait Graph { fn f(&self, Edge); + fn g(&self, Node); } @@ -24,6 +25,9 @@ impl Graph for HashMap { fn f(&self, _e: E) { panic!(); } + fn g(&self, _e: int) { + panic!(); + } } pub fn main() { diff --git a/src/test/run-pass/issue-6318.rs b/src/test/run-pass/issue-6318.rs index 1d8fe8bfce82c..6e608d34bd578 100644 --- a/src/test/run-pass/issue-6318.rs +++ b/src/test/run-pass/issue-6318.rs @@ -15,7 +15,9 @@ pub enum Thing { A(Box) } -pub trait Foo {} +pub trait Foo { + fn dummy(&self) { } +} pub struct Struct; diff --git a/src/test/run-pass/issue-7575.rs b/src/test/run-pass/issue-7575.rs index 225213db6a425..77cfc7f0cf607 100644 --- a/src/test/run-pass/issue-7575.rs +++ b/src/test/run-pass/issue-7575.rs @@ -10,6 +10,7 @@ trait Foo { fn new() -> bool { false } + fn dummy(&self) { } } trait Bar { diff --git a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs index b6dfbb1ca42ad..736860947f23c 100644 --- a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs +++ b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs @@ -19,7 +19,10 @@ pub fn main() {} -trait A {} +trait A { + fn dummy(&self) { } +} + impl A for T {} fn owned2(a: Box) { a as Box; } diff --git a/src/test/run-pass/issue-7911.rs b/src/test/run-pass/issue-7911.rs index 86948ebcb91e0..3eb593708bee8 100644 --- a/src/test/run-pass/issue-7911.rs +++ b/src/test/run-pass/issue-7911.rs @@ -14,7 +14,9 @@ // with different mutability in macro in two methods #![allow(unused_variable)] // unused foobar_immut + foobar_mut -trait FooBar {} +trait FooBar { + fn dummy(&self) { } +} struct Bar(i32); struct Foo { bar: Bar } diff --git a/src/test/run-pass/issue-8248.rs b/src/test/run-pass/issue-8248.rs index 377b9ce262c73..7bc8dbe616ff3 100644 --- a/src/test/run-pass/issue-8248.rs +++ b/src/test/run-pass/issue-8248.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait A {} +trait A { + fn dummy(&self) { } +} struct B; impl A for B {} diff --git a/src/test/run-pass/issue-8249.rs b/src/test/run-pass/issue-8249.rs index 44f07def531bc..83c9e9bf45053 100644 --- a/src/test/run-pass/issue-8249.rs +++ b/src/test/run-pass/issue-8249.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait A {} +trait A { + fn dummy(&self) { } +} struct B; impl A for B {} diff --git a/src/test/run-pass/issue-9719.rs b/src/test/run-pass/issue-9719.rs index 8fc86eb49e769..aa1e65efaa41e 100644 --- a/src/test/run-pass/issue-9719.rs +++ b/src/test/run-pass/issue-9719.rs @@ -13,7 +13,9 @@ mod a { A(T), } - pub trait X {} + pub trait X { + fn dummy(&self) { } + } impl X for int {} pub struct Z<'a>(Enum<&'a (X+'a)>); @@ -21,7 +23,9 @@ mod a { } mod b { - trait X {} + trait X { + fn dummy(&self) { } + } impl X for int {} struct Y<'a>{ x:Option<&'a (X+'a)>, diff --git a/src/test/run-pass/lint-cstack.rs b/src/test/run-pass/lint-cstack.rs index 2194453aac29a..f180ffcd4e823 100644 --- a/src/test/run-pass/lint-cstack.rs +++ b/src/test/run-pass/lint-cstack.rs @@ -15,7 +15,7 @@ extern { } trait A { - fn foo() { + fn foo(&self) { unsafe { rust_get_test_int(); } diff --git a/src/test/run-pass/method-early-bound-lifetimes-on-self.rs b/src/test/run-pass/method-early-bound-lifetimes-on-self.rs index 25ce0d774ebc1..cec9753a2feca 100644 --- a/src/test/run-pass/method-early-bound-lifetimes-on-self.rs +++ b/src/test/run-pass/method-early-bound-lifetimes-on-self.rs @@ -13,7 +13,11 @@ #![allow(dead_code)] -struct Cursor<'a>; +use std::marker; + +struct Cursor<'a> { + m: marker::PhantomData<&'a ()> +} trait CursorNavigator { fn init_cursor<'a, 'b:'a>(&'a self, cursor: &mut Cursor<'b>) -> bool; @@ -28,7 +32,7 @@ impl CursorNavigator for SimpleNavigator { } fn main() { - let mut c = Cursor; + let mut c = Cursor { m: marker::PhantomData }; let n = SimpleNavigator; n.init_cursor(&mut c); } diff --git a/src/test/run-pass/method-recursive-blanket-impl.rs b/src/test/run-pass/method-recursive-blanket-impl.rs index 338bd89ab5cb1..15eb2ae2e4b49 100644 --- a/src/test/run-pass/method-recursive-blanket-impl.rs +++ b/src/test/run-pass/method-recursive-blanket-impl.rs @@ -17,16 +17,16 @@ use std::marker::Sized; // Note: this must be generic for the problem to show up trait Foo { - fn foo(&self); + fn foo(&self, a: A); } impl Foo for [u8] { - fn foo(&self) {} + fn foo(&self, a: u8) {} } impl<'a, A, T> Foo for &'a T where T: Foo { - fn foo(&self) { - Foo::foo(*self) + fn foo(&self, a: A) { + Foo::foo(*self, a) } } diff --git a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs b/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs index eb17aa78bd9a8..1164ef1a3c98e 100644 --- a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs +++ b/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs @@ -8,8 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::marker::MarkerTrait; -trait Serializer { +trait Serializer : MarkerTrait { } trait Serializable { diff --git a/src/test/run-pass/overloaded-autoderef-vtable.rs b/src/test/run-pass/overloaded-autoderef-vtable.rs index be2b309b8217f..d50f2efe0e7b4 100644 --- a/src/test/run-pass/overloaded-autoderef-vtable.rs +++ b/src/test/run-pass/overloaded-autoderef-vtable.rs @@ -11,7 +11,8 @@ use std::ops::Deref; struct DerefWithHelper { - helper: H + helper: H, + value: T } trait Helper { @@ -39,6 +40,7 @@ impl Foo { } pub fn main() { - let x: DerefWithHelper, Foo> = DerefWithHelper { helper: Some(Foo {x: 5}) }; + let x: DerefWithHelper, Foo> = + DerefWithHelper { helper: Some(Foo {x: 5}), value: Foo { x: 2 } }; assert!(x.foo() == 5); } diff --git a/src/test/run-pass/overloaded-calls-param-vtables.rs b/src/test/run-pass/overloaded-calls-param-vtables.rs index 2838909c1be62..2ef9e08134cf7 100644 --- a/src/test/run-pass/overloaded-calls-param-vtables.rs +++ b/src/test/run-pass/overloaded-calls-param-vtables.rs @@ -12,10 +12,11 @@ #![feature(unboxed_closures)] +use std::marker::PhantomData; use std::ops::Fn; use std::ops::Add; -struct G; +struct G(PhantomData); impl<'a, A: Add> Fn<(A,)> for G { type Output = i32; @@ -27,5 +28,5 @@ impl<'a, A: Add> Fn<(A,)> for G { fn main() { // ICE trigger - G(1_i32); + (G(PhantomData))(1_i32); } diff --git a/src/test/run-pass/parameterized-trait-with-bounds.rs b/src/test/run-pass/parameterized-trait-with-bounds.rs index 840e58848a742..061c9168955a4 100644 --- a/src/test/run-pass/parameterized-trait-with-bounds.rs +++ b/src/test/run-pass/parameterized-trait-with-bounds.rs @@ -11,12 +11,12 @@ #![allow(dead_code)] -trait A {} -trait B {} -trait C<'a, U> {} +trait A { fn get(self) -> T; } +trait B { fn get(self) -> (T,U); } +trait C<'a, U> { fn get(self) -> &'a U; } mod foo { - pub trait D<'a, T> {} + pub trait D<'a, T> { fn get(self) -> &'a T; } } fn foo1(_: &(A + Send)) {} diff --git a/src/test/run-pass/privacy-ns.rs b/src/test/run-pass/privacy-ns.rs index f3380352f5fa9..e9b8e694d6060 100644 --- a/src/test/run-pass/privacy-ns.rs +++ b/src/test/run-pass/privacy-ns.rs @@ -19,6 +19,7 @@ // public type, private value pub mod foo1 { pub trait Bar { + fn dummy(&self) { } } pub struct Baz; @@ -50,6 +51,7 @@ fn test_glob1() { // private type, public value pub mod foo2 { trait Bar { + fn dummy(&self) { } } pub struct Baz; @@ -81,6 +83,7 @@ fn test_glob2() { // public type, public value pub mod foo3 { pub trait Bar { + fn dummy(&self) { } } pub struct Baz; diff --git a/src/test/run-pass/regions-assoc-type-static-bound.rs b/src/test/run-pass/regions-assoc-type-static-bound.rs index 6b629a9035db2..80ae371e5091e 100644 --- a/src/test/run-pass/regions-assoc-type-static-bound.rs +++ b/src/test/run-pass/regions-assoc-type-static-bound.rs @@ -11,7 +11,10 @@ // Test that the compiler considers the 'static bound declared in the // trait. Issue #20890. -trait Foo { type Value: 'static; } +trait Foo { + type Value: 'static; + fn dummy(&self) { } +} fn require_static() {} diff --git a/src/test/run-pass/regions-bound-lists-feature-gate-2.rs b/src/test/run-pass/regions-bound-lists-feature-gate-2.rs index 0a95a89d57c32..a06e0f6da785a 100644 --- a/src/test/run-pass/regions-bound-lists-feature-gate-2.rs +++ b/src/test/run-pass/regions-bound-lists-feature-gate-2.rs @@ -12,7 +12,9 @@ #![feature(issue_5723_bootstrap)] -trait Foo { } +trait Foo { + fn dummy(&self) { } +} fn foo<'a, 'b, 'c:'a+'b, 'd>() { } diff --git a/src/test/run-pass/regions-bound-lists-feature-gate.rs b/src/test/run-pass/regions-bound-lists-feature-gate.rs index c5baecf7272fa..996583dc6de93 100644 --- a/src/test/run-pass/regions-bound-lists-feature-gate.rs +++ b/src/test/run-pass/regions-bound-lists-feature-gate.rs @@ -12,8 +12,9 @@ #![feature(issue_5723_bootstrap)] - -trait Foo { } +trait Foo { + fn dummy(&self) { } +} fn foo<'a>(x: Box) { } diff --git a/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs b/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs index 978383c244780..bdc0d41c94e82 100644 --- a/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs +++ b/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs @@ -14,6 +14,8 @@ // lifetime parameters must be early bound in the type of the // associated item. +use std::marker; + pub enum Value<'v> { A(&'v str), B, @@ -23,7 +25,9 @@ pub trait Decoder<'v> { fn read(&mut self) -> Value<'v>; } -pub trait Decodable<'v, D: Decoder<'v>> { +pub trait Decodable<'v, D: Decoder<'v>> + : marker::PhantomFn<(), &'v int> +{ fn decode(d: &mut D) -> Self; } diff --git a/src/test/run-pass/regions-early-bound-trait-param.rs b/src/test/run-pass/regions-early-bound-trait-param.rs index 6fcfaf58a023b..3f434a4838d42 100644 --- a/src/test/run-pass/regions-early-bound-trait-param.rs +++ b/src/test/run-pass/regions-early-bound-trait-param.rs @@ -53,11 +53,11 @@ fn field_invoke2<'l, 'm, 'n>(x: &'n Struct2<'l,'m>) -> int { x.f.short() } -trait MakerTrait<'o> { +trait MakerTrait { fn mk() -> Self; } -fn make_val<'p, T:MakerTrait<'p>>() -> T { +fn make_val() -> T { MakerTrait::mk() } @@ -80,7 +80,7 @@ impl<'s> Trait<'s> for (int,int) { } } -impl<'t> MakerTrait<'t> for Box+'static> { +impl<'t> MakerTrait for Box+'static> { fn mk() -> Box+'static> { box() (4,5) as Box } } diff --git a/src/test/run-pass/regions-infer-bivariance.rs b/src/test/run-pass/regions-infer-bivariance.rs deleted file mode 100644 index a3288e2e1b90b..0000000000000 --- a/src/test/run-pass/regions-infer-bivariance.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2012 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. - -// Test that a type whose lifetime parameters is never used is -// inferred to be bivariant. - -use std::marker; - -struct Bivariant<'a>; - -fn use1<'short,'long>(c: Bivariant<'short>, - _where:Option<&'short &'long ()>) { - let _: Bivariant<'long> = c; -} - -fn use2<'short,'long>(c: Bivariant<'long>, - _where:Option<&'short &'long ()>) { - let _: Bivariant<'short> = c; -} - -pub fn main() {} diff --git a/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs b/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs index d3464f01203ac..5964ac65d5f6e 100644 --- a/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs +++ b/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs @@ -10,7 +10,9 @@ #![feature(unsafe_destructor)] -pub struct Foo; +use std::marker; + +pub struct Foo(marker::PhantomData); impl Iterator for Foo { type Item = T; diff --git a/src/test/run-pass/regions-no-variance-from-fn-generics.rs b/src/test/run-pass/regions-no-variance-from-fn-generics.rs index a35ab1bfc0ce6..80c478afa644f 100644 --- a/src/test/run-pass/regions-no-variance-from-fn-generics.rs +++ b/src/test/run-pass/regions-no-variance-from-fn-generics.rs @@ -12,7 +12,9 @@ // should not upset the variance inference for actual occurrences of // that lifetime in type expressions. -pub trait HasLife<'a> { } +pub trait HasLife<'a> { + fn dummy(&'a self) { } // just to induce a variance on 'a +} trait UseLife01 { fn refs<'a, H: HasLife<'a>>(&'a self) -> H; @@ -23,7 +25,11 @@ trait UseLife02 { } -pub trait HasType { } +pub trait HasType +{ + fn dummy(&self, t: T) -> T { panic!() } +} + trait UseLife03 { fn refs<'a, H: HasType<&'a T>>(&'a self) -> H; diff --git a/src/test/run-pass/self-impl.rs b/src/test/run-pass/self-impl.rs index 40a4dc52a70b3..af2b2de8ab8ba 100644 --- a/src/test/run-pass/self-impl.rs +++ b/src/test/run-pass/self-impl.rs @@ -29,6 +29,7 @@ pub struct Baz { trait Bar { fn bar(x: Self, y: &Self, z: Box) -> Self; + fn dummy(&self, x: X) { } } impl Bar for Box> { diff --git a/src/test/run-pass/simple-match-generic-tag.rs b/src/test/run-pass/simple-match-generic-tag.rs index 7ed8cb434caf5..2217dddbd21f0 100644 --- a/src/test/run-pass/simple-match-generic-tag.rs +++ b/src/test/run-pass/simple-match-generic-tag.rs @@ -8,11 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - - -enum opt { none, } +enum opt { none, some(T) } pub fn main() { let x = opt::none::; - match x { opt::none:: => { println!("hello world"); } } + match x { + opt::none:: => { println!("hello world"); } + opt::some(_) => { } + } } diff --git a/src/test/run-pass/syntax-trait-polarity.rs b/src/test/run-pass/syntax-trait-polarity.rs index 3344844d49ff7..340ad2a531a73 100644 --- a/src/test/run-pass/syntax-trait-polarity.rs +++ b/src/test/run-pass/syntax-trait-polarity.rs @@ -10,17 +10,17 @@ #![feature(optin_builtin_traits)] -use std::marker::Send; +use std::marker::{MarkerTrait, Send}; struct TestType; impl TestType {} -trait TestTrait {} +trait TestTrait : MarkerTrait {} impl !Send for TestType {} -struct TestType2; +struct TestType2(T); impl TestType2 {} diff --git a/src/test/run-pass/trailing-comma.rs b/src/test/run-pass/trailing-comma.rs index b5ae259bc630e..76c62a83e758c 100644 --- a/src/test/run-pass/trailing-comma.rs +++ b/src/test/run-pass/trailing-comma.rs @@ -12,7 +12,7 @@ fn f(_: T,) {} -struct Foo; +struct Foo(T); struct Bar; @@ -34,7 +34,7 @@ pub fn main() { let [_, _, .., _,] = [1, 1, 1, 1,]; let [_, _, _.., _,] = [1, 1, 1, 1,]; - let x: Foo = Foo::; + let x: Foo = Foo::(1); Bar::f(0,); Bar.g(0,); diff --git a/src/test/run-pass/trait-bounds-basic.rs b/src/test/run-pass/trait-bounds-basic.rs index d03496403ad2a..ed25bf8b02e88 100644 --- a/src/test/run-pass/trait-bounds-basic.rs +++ b/src/test/run-pass/trait-bounds-basic.rs @@ -9,7 +9,7 @@ // except according to those terms. -trait Foo { +trait Foo : ::std::marker::MarkerTrait { } fn b(_x: Box) { diff --git a/src/test/run-pass/trait-bounds-on-structs-and-enums.rs b/src/test/run-pass/trait-bounds-on-structs-and-enums.rs index e3234f037547b..976120908b27a 100644 --- a/src/test/run-pass/trait-bounds-on-structs-and-enums.rs +++ b/src/test/run-pass/trait-bounds-on-structs-and-enums.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait U {} -trait T {} +trait U : ::std::marker::MarkerTrait {} +trait T { fn get(self) -> X; } -trait S2 { +trait S2 : ::std::marker::MarkerTrait { fn m(x: Box+'static>) {} } diff --git a/src/test/run-pass/trait-bounds-recursion.rs b/src/test/run-pass/trait-bounds-recursion.rs index 49f8999cd45e4..7135dad7d190c 100644 --- a/src/test/run-pass/trait-bounds-recursion.rs +++ b/src/test/run-pass/trait-bounds-recursion.rs @@ -10,17 +10,17 @@ trait I { fn i(&self) -> Self; } -trait A { +trait A : ::std::marker::MarkerTrait { fn id(x:T) -> T { x.i() } } -trait J { fn j(&self) -> Self; } +trait J { fn j(&self) -> T; } -trait B> { +trait B> : ::std::marker::MarkerTrait { fn id(x:T) -> T { x.j() } } -trait C { +trait C : ::std::marker::MarkerTrait { fn id>(x:T) -> T { x.j() } } diff --git a/src/test/run-pass/trait-default-method-bound-subst4.rs b/src/test/run-pass/trait-default-method-bound-subst4.rs index fdc42e58f8cac..c9165050b9326 100644 --- a/src/test/run-pass/trait-default-method-bound-subst4.rs +++ b/src/test/run-pass/trait-default-method-bound-subst4.rs @@ -11,6 +11,7 @@ trait A { fn g(&self, x: uint) -> uint { x } + fn h(&self, x: T) { } } impl A for int { } diff --git a/src/test/run-pass/trait-impl.rs b/src/test/run-pass/trait-impl.rs index 16ef315c206d5..bd2bf430a686c 100644 --- a/src/test/run-pass/trait-impl.rs +++ b/src/test/run-pass/trait-impl.rs @@ -16,7 +16,8 @@ use traitimpl::Bar; static mut COUNT: uint = 1; -trait T {} +trait T : ::std::marker::MarkerTrait { +} impl<'a> T+'a { fn foo(&self) { diff --git a/src/test/run-pass/trait-inheritance-num2.rs b/src/test/run-pass/trait-inheritance-num2.rs index 1e6e7227a067c..f89eea46090d0 100644 --- a/src/test/run-pass/trait-inheritance-num2.rs +++ b/src/test/run-pass/trait-inheritance-num2.rs @@ -14,8 +14,7 @@ use std::cmp::{PartialEq, PartialOrd}; use std::num::NumCast; -pub trait TypeExt {} - +pub trait TypeExt : ::std::marker::MarkerTrait { } impl TypeExt for u8 {} impl TypeExt for u16 {} diff --git a/src/test/run-pass/trait-inheritance-static2.rs b/src/test/run-pass/trait-inheritance-static2.rs index 3b454aad03e48..8f3b325a513fe 100644 --- a/src/test/run-pass/trait-inheritance-static2.rs +++ b/src/test/run-pass/trait-inheritance-static2.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait MyEq { } +pub trait MyEq : ::std::marker::MarkerTrait { } -pub trait MyNum { +pub trait MyNum : ::std::marker::MarkerTrait { fn from_int(int) -> Self; } diff --git a/src/test/run-pass/trait-object-generics.rs b/src/test/run-pass/trait-object-generics.rs index 76352c799a0f2..6f89490716f08 100644 --- a/src/test/run-pass/trait-object-generics.rs +++ b/src/test/run-pass/trait-object-generics.rs @@ -13,11 +13,14 @@ #![allow(unknown_features)] #![feature(box_syntax)] +use std::marker; + pub trait Trait2 { - fn doit(&self); + fn doit(&self) -> A; } pub struct Impl { + m1: marker::PhantomData<(A1,A2,A3)>, /* * With A2 we get the ICE: * task failed at 'index out of bounds: the len is 1 but the index is 1', @@ -28,13 +31,13 @@ pub struct Impl { impl Impl { pub fn step(&self) { - self.t.doit() + self.t.doit(); } } // test for #8601 -enum Type { Constant } +enum Type { Constant(T) } trait Trait { fn method(&self,Type<(K,V)>) -> int; @@ -46,5 +49,5 @@ impl Trait for () { pub fn main() { let a = box() () as Box>; - assert_eq!(a.method(Type::Constant), 0); + assert_eq!(a.method(Type::Constant((1u8, 2u8))), 0); } diff --git a/src/test/run-pass/trait-static-method-overwriting.rs b/src/test/run-pass/trait-static-method-overwriting.rs index a8cea24db0c0c..10439d5c86aa3 100644 --- a/src/test/run-pass/trait-static-method-overwriting.rs +++ b/src/test/run-pass/trait-static-method-overwriting.rs @@ -10,7 +10,7 @@ // except according to those terms. mod base { - pub trait HasNew { + pub trait HasNew { fn new() -> Self; } @@ -18,7 +18,7 @@ mod base { dummy: (), } - impl ::base::HasNew for Foo { + impl ::base::HasNew for Foo { fn new() -> Foo { println!("Foo"); Foo { dummy: () } @@ -29,7 +29,7 @@ mod base { dummy: (), } - impl ::base::HasNew for Bar { + impl ::base::HasNew for Bar { fn new() -> Bar { println!("Bar"); Bar { dummy: () } @@ -38,6 +38,6 @@ mod base { } pub fn main() { - let _f: base::Foo = base::HasNew::::new(); - let _b: base::Bar = base::HasNew::::new(); + let _f: base::Foo = base::HasNew::new(); + let _b: base::Bar = base::HasNew::new(); } diff --git a/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs b/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs index 1f9b821178c46..2d1ba7f39b27b 100644 --- a/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs +++ b/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs @@ -10,7 +10,7 @@ #![feature(core,unboxed_closures)] -use std::marker::CovariantType; +use std::marker::PhantomData; // Test that we are able to infer a suitable kind for a "recursive" // closure. As far as I can tell, coding up a recursive closure @@ -20,12 +20,12 @@ use std::marker::CovariantType; struct YCombinator { func: F, - marker: CovariantType<(A,R)>, + marker: PhantomData<(A,R)>, } impl YCombinator { fn new(f: F) -> YCombinator { - YCombinator { func: f, marker: CovariantType } + YCombinator { func: f, marker: PhantomData } } } diff --git a/src/test/run-pass/unique-object-move.rs b/src/test/run-pass/unique-object-move.rs index cec523a06712e..1d4eb0a75232d 100644 --- a/src/test/run-pass/unique-object-move.rs +++ b/src/test/run-pass/unique-object-move.rs @@ -13,7 +13,7 @@ #![allow(unknown_features)] #![feature(box_syntax)] -pub trait EventLoop { } +pub trait EventLoop : ::std::marker::MarkerTrait { } pub struct UvEventLoop { uvio: int diff --git a/src/test/run-pass/unsized.rs b/src/test/run-pass/unsized.rs index e6dd8d46952eb..ae175d27b0a4e 100644 --- a/src/test/run-pass/unsized.rs +++ b/src/test/run-pass/unsized.rs @@ -12,17 +12,19 @@ // Test syntax checks for `?Sized` syntax. -trait T1 {} -pub trait T2 {} -trait T3 : T2 {} -trait T4 {} -trait T5 {} -trait T6 {} -trait T7 {} -trait T8 {} -trait T9 {} -struct S1; -enum E {} +use std::marker::{PhantomData, PhantomFn}; + +trait T1 : PhantomFn { } +pub trait T2 : PhantomFn { } +trait T3 : T2 + PhantomFn { } +trait T4 : PhantomFn<(Self,X)> {} +trait T5 : PhantomFn<(Self,X,Y)> {} +trait T6 : PhantomFn<(Self,X,Y)> {} +trait T7 : PhantomFn<(Self,X,Y)> {} +trait T8 : PhantomFn<(Self,X)> {} +trait T9 : PhantomFn<(Self,X)> {} +struct S1(PhantomData); +enum E { E1(PhantomData) } impl T1 for S1 {} fn f() {} type TT = T; diff --git a/src/test/run-pass/unsized2.rs b/src/test/run-pass/unsized2.rs index 285100dd7197c..10b2f2fb70924 100644 --- a/src/test/run-pass/unsized2.rs +++ b/src/test/run-pass/unsized2.rs @@ -15,6 +15,8 @@ // Test sized-ness checking in substitution. +use std::marker; + // Unbounded. fn f1(x: &X) { f1::(x); @@ -25,7 +27,7 @@ fn f2(x: &X) { } // Bounded. -trait T {} +trait T { fn dummy(&self) { } } fn f3(x: &X) { f3::(x); } @@ -66,20 +68,24 @@ fn f7(x: &X) { } trait T4 { - fn m1(x: &T4); - fn m2(x: &T5); + fn dummy(&self) { } + fn m1(x: &T4, y: X); + fn m2(x: &T5, y: X); } trait T5 { + fn dummy(&self) { } // not an error (for now) fn m1(x: &T4); fn m2(x: &T5); } trait T6 { + fn dummy(&self) { } fn m1(x: &T4); fn m2(x: &T5); } trait T7 { + fn dummy(&self) { } // not an error (for now) fn m1(x: &T4); fn m2(x: &T5); diff --git a/src/test/run-pass/visible-private-types-feature-gate.rs b/src/test/run-pass/visible-private-types-feature-gate.rs index 9518671b4799d..46e93b25697bb 100644 --- a/src/test/run-pass/visible-private-types-feature-gate.rs +++ b/src/test/run-pass/visible-private-types-feature-gate.rs @@ -10,7 +10,7 @@ #![feature(visible_private_types)] -trait Foo {} +trait Foo { fn dummy(&self) { } } pub trait Bar : Foo {} diff --git a/src/test/run-pass/where-clause-bounds-inconsistency.rs b/src/test/run-pass/where-clause-bounds-inconsistency.rs index a1a61127f68e0..3374f47ed5f80 100644 --- a/src/test/run-pass/where-clause-bounds-inconsistency.rs +++ b/src/test/run-pass/where-clause-bounds-inconsistency.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Bound {} +trait Bound { + fn dummy(&self) { } +} trait Trait { fn a(&self, T) where T: Bound; diff --git a/src/test/run-pass/where-clause-early-bound-lifetimes.rs b/src/test/run-pass/where-clause-early-bound-lifetimes.rs index cade99b83a2fe..4a149d4d3df44 100644 --- a/src/test/run-pass/where-clause-early-bound-lifetimes.rs +++ b/src/test/run-pass/where-clause-early-bound-lifetimes.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait TheTrait { } +trait TheTrait { fn dummy(&self) { } } impl TheTrait for &'static int { } diff --git a/src/test/run-pass/where-clause-method-substituion.rs b/src/test/run-pass/where-clause-method-substituion.rs index b391df8500bb7..ecc210ea579db 100644 --- a/src/test/run-pass/where-clause-method-substituion.rs +++ b/src/test/run-pass/where-clause-method-substituion.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo {} +trait Foo { fn dummy(&self, arg: T) { } } trait Bar { fn method(&self) where A: Foo; @@ -19,7 +19,7 @@ struct X; impl Foo for X {} -impl Bar for int { +impl Bar for i32 { fn method(&self) where X: Foo { } } diff --git a/src/test/run-pass/where-for-self.rs b/src/test/run-pass/where-for-self.rs index 5d426793c2e36..1fd223b0dd3f6 100644 --- a/src/test/run-pass/where-for-self.rs +++ b/src/test/run-pass/where-for-self.rs @@ -11,13 +11,19 @@ // Test that we can quantify lifetimes outside a constraint (i.e., including // the self type) in a where clause. +use std::marker::PhantomFn; + static mut COUNT: u32 = 1; -trait Bar<'a> { +trait Bar<'a> + : PhantomFn<&'a ()> +{ fn bar(&self); } -trait Baz<'a> { +trait Baz<'a> + : PhantomFn<&'a ()> +{ fn baz(&self); } From 60f507be45f7ae8f5ff119316def0ccb3735a479 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 12:32:37 -0500 Subject: [PATCH 33/76] Fallout: remove unused type and region parameters. --- src/librustc/middle/expr_use_visitor.rs | 13 +++++-------- src/librustc/middle/infer/higher_ranked/mod.rs | 4 ++-- src/librustc_typeck/check/method/suggest.rs | 4 ++-- src/libstd/old_io/mod.rs | 4 ++-- src/libsyntax/std_inject.rs | 11 ++++++----- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 5cc7502b5128d..bab954c29596f 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -29,7 +29,6 @@ use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam}; use middle::ty::{MethodStatic, MethodStaticClosure}; use util::ppaux::Repr; -use std::marker; use syntax::{ast, ast_util}; use syntax::ptr::P; use syntax::codemap::Span; @@ -128,16 +127,14 @@ pub enum MatchMode { MovingMatch, } -#[derive(PartialEq,Debug)] -enum TrackMatchMode { +#[derive(Copy, PartialEq, Debug)] +enum TrackMatchMode { Unknown, Definite(MatchMode), Conflicting, } -impl marker::Copy for TrackMatchMode {} - -impl TrackMatchMode { +impl TrackMatchMode { // Builds up the whole match mode for a pattern from its constituent // parts. The lattice looks like this: // @@ -931,7 +928,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { return true; } - fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm) -> TrackMatchMode { + fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm) -> TrackMatchMode { let mut mode = Unknown; for pat in &arm.pats { self.determine_pat_move_mode(discr_cmt.clone(), &**pat, &mut mode); @@ -966,7 +963,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { fn determine_pat_move_mode(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &ast::Pat, - mode: &mut TrackMatchMode) { + mode: &mut TrackMatchMode) { debug!("determine_pat_move_mode cmt_discr={} pat={}", cmt_discr.repr(self.tcx()), pat.repr(self.tcx())); return_if_err!(self.mc.cat_pattern(cmt_discr, pat, |_mc, cmt_pat, pat| { diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs index 4469e27a5b05a..a729156c88b35 100644 --- a/src/librustc/middle/infer/higher_ranked/mod.rs +++ b/src/librustc/middle/infer/higher_ranked/mod.rs @@ -31,7 +31,7 @@ pub trait HigherRankedRelations<'tcx> { where T : Combineable<'tcx>; } -trait InferCtxtExt<'tcx> { +trait InferCtxtExt { fn tainted_regions(&self, snapshot: &CombinedSnapshot, r: ty::Region) -> Vec; fn region_vars_confined_to_snapshot(&self, @@ -371,7 +371,7 @@ fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>, })) } -impl<'a,'tcx> InferCtxtExt<'tcx> for InferCtxt<'a,'tcx> { +impl<'a,'tcx> InferCtxtExt for InferCtxt<'a,'tcx> { fn tainted_regions(&self, snapshot: &CombinedSnapshot, r: ty::Region) -> Vec { self.region_vars.tainted(&snapshot.region_vars_snapshot, r) } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 063300a1d7280..796da951439bc 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -306,10 +306,10 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { // Crate-local: // // meh. - struct Visitor<'a, 'b: 'a, 'tcx: 'a + 'b> { + struct Visitor<'a> { traits: &'a mut AllTraitsVec, } - impl<'v,'a, 'b, 'tcx> visit::Visitor<'v> for Visitor<'a, 'b, 'tcx> { + impl<'v, 'a> visit::Visitor<'v> for Visitor<'a> { fn visit_item(&mut self, i: &'v ast::Item) { match i.node { ast::ItemTrait(..) => { diff --git a/src/libstd/old_io/mod.rs b/src/libstd/old_io/mod.rs index 4bd0662232fec..9655da92e5697 100644 --- a/src/libstd/old_io/mod.rs +++ b/src/libstd/old_io/mod.rs @@ -433,7 +433,7 @@ pub enum IoErrorKind { } /// A trait that lets you add a `detail` to an IoError easily -trait UpdateIoError { +trait UpdateIoError { /// Returns an IoError with updated description and detail fn update_err(self, desc: &'static str, detail: D) -> Self where D: FnOnce(&IoError) -> String; @@ -446,7 +446,7 @@ trait UpdateIoError { fn update_desc(self, desc: &'static str) -> Self; } -impl UpdateIoError for IoResult { +impl UpdateIoError for IoResult { fn update_err(self, desc: &'static str, detail: D) -> IoResult where D: FnOnce(&IoError) -> String, { diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 98c193c7e6b85..fcb1cdf216b42 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -45,11 +45,11 @@ fn no_prelude(attrs: &[ast::Attribute]) -> bool { attr::contains_name(attrs, "no_implicit_prelude") } -struct StandardLibraryInjector<'a> { - alt_std_name: Option +struct StandardLibraryInjector { + alt_std_name: Option, } -impl<'a> fold::Folder for StandardLibraryInjector<'a> { +impl fold::Folder for StandardLibraryInjector { fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { // The name to use in `extern crate "name" as std;` @@ -80,9 +80,10 @@ fn inject_crates_ref(krate: ast::Crate, alt_std_name: Option) -> ast::Cr fold.fold_crate(krate) } -struct PreludeInjector<'a>; +struct PreludeInjector; -impl<'a> fold::Folder for PreludeInjector<'a> { + +impl fold::Folder for PreludeInjector { fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { // only add `use std::prelude::*;` if there wasn't a // `#![no_implicit_prelude]` at the crate level. From aaf4176f0f7b072487d8f6ca4720d6da6315b23f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 12:34:04 -0500 Subject: [PATCH 34/76] Fallout: Port slice to use `PhantomData` instead of `ContravariantLifetime` --- src/libcore/slice.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index bbfe7e58ef4ac..a86da53b372a9 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -140,11 +140,11 @@ impl SliceExt for [T] { if mem::size_of::() == 0 { Iter {ptr: p, end: (p as usize + self.len()) as *const T, - marker: marker::ContravariantLifetime::<'a>} + _marker: marker::PhantomData} } else { Iter {ptr: p, end: p.offset(self.len() as isize), - marker: marker::ContravariantLifetime::<'a>} + _marker: marker::PhantomData} } } } @@ -279,11 +279,11 @@ impl SliceExt for [T] { if mem::size_of::() == 0 { IterMut {ptr: p, end: (p as usize + self.len()) as *mut T, - marker: marker::ContravariantLifetime::<'a>} + _marker: marker::PhantomData} } else { IterMut {ptr: p, end: p.offset(self.len() as isize), - marker: marker::ContravariantLifetime::<'a>} + _marker: marker::PhantomData} } } } @@ -733,7 +733,7 @@ macro_rules! make_slice { pub struct Iter<'a, T: 'a> { ptr: *const T, end: *const T, - marker: marker::ContravariantLifetime<'a> + _marker: marker::PhantomData<&'a T>, } #[unstable(feature = "core")] @@ -790,7 +790,7 @@ impl<'a, T> ExactSizeIterator for Iter<'a, T> {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Clone for Iter<'a, T> { - fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, marker: self.marker } } + fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } } } #[unstable(feature = "core", reason = "trait is experimental")] @@ -823,7 +823,7 @@ impl<'a, T> RandomAccessIterator for Iter<'a, T> { pub struct IterMut<'a, T: 'a> { ptr: *mut T, end: *mut T, - marker: marker::ContravariantLifetime<'a>, + _marker: marker::PhantomData<&'a mut T>, } From 2953710d26515ee2832ae6f705f51d00526fa018 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 12:35:05 -0500 Subject: [PATCH 35/76] Fallout: port libflate to new Unique API --- src/libflate/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index ff6400a11dfe8..24660b3f396c1 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -45,13 +45,13 @@ pub struct Bytes { impl Deref for Bytes { type Target = [u8]; fn deref(&self) -> &[u8] { - unsafe { slice::from_raw_parts_mut(self.ptr.ptr, self.len) } + unsafe { slice::from_raw_parts(*self.ptr, self.len) } } } impl Drop for Bytes { fn drop(&mut self) { - unsafe { libc::free(self.ptr.ptr as *mut _); } + unsafe { libc::free(*self.ptr as *mut _); } } } @@ -84,7 +84,7 @@ fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option { &mut outsz, flags); if !res.is_null() { - let res = Unique(res as *mut u8); + let res = Unique::new(res as *mut u8); Some(Bytes { ptr: res, len: outsz as uint }) } else { None @@ -110,7 +110,7 @@ fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option { &mut outsz, flags); if !res.is_null() { - let res = Unique(res as *mut u8); + let res = Unique::new(res as *mut u8); Some(Bytes { ptr: res, len: outsz as uint }) } else { None From 199b992e6306ead7a2be1e086768879983c08a20 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 12:41:03 -0500 Subject: [PATCH 36/76] Fallout: add phantom data to librand --- src/librand/distributions/mod.rs | 11 +++++++++-- src/librand/lib.rs | 4 +++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs index d1d24cea8714e..5a85552dc384e 100644 --- a/src/librand/distributions/mod.rs +++ b/src/librand/distributions/mod.rs @@ -21,6 +21,7 @@ use core::prelude::*; use core::num::{Float, Int}; +use core::marker::PhantomData; use {Rng, Rand}; @@ -56,7 +57,13 @@ pub trait IndependentSample: Sample { /// A wrapper for generating types that implement `Rand` via the /// `Sample` & `IndependentSample` traits. -pub struct RandSample; +pub struct RandSample { _marker: PhantomData } + +impl RandSample { + pub fn new() -> RandSample { + RandSample { _marker: PhantomData } + } +} impl Sample for RandSample { fn sample(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) } @@ -285,7 +292,7 @@ mod tests { #[test] fn test_rand_sample() { - let mut rand_sample = RandSample::; + let mut rand_sample = RandSample::::new(); assert_eq!(rand_sample.sample(&mut ::test::rng()), ConstRand(0)); assert_eq!(rand_sample.ind_sample(&mut ::test::rng()), ConstRand(0)); diff --git a/src/librand/lib.rs b/src/librand/lib.rs index 915c70bbf8ce1..7588bf7c5158e 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -41,6 +41,7 @@ extern crate core; #[cfg(test)] #[macro_use] extern crate log; use core::prelude::*; +use core::marker::PhantomData; pub use isaac::{IsaacRng, Isaac64Rng}; pub use chacha::ChaChaRng; @@ -206,7 +207,7 @@ pub trait Rng : Sized { /// .collect::>()); /// ``` fn gen_iter<'a, T: Rand>(&'a mut self) -> Generator<'a, T, Self> { - Generator { rng: self } + Generator { rng: self, _marker: PhantomData } } /// Generate a random value in the range [`low`, `high`). @@ -317,6 +318,7 @@ pub trait Rng : Sized { /// This iterator is created via the `gen_iter` method on `Rng`. pub struct Generator<'a, T, R:'a> { rng: &'a mut R, + _marker: PhantomData } impl<'a, T: Rand, R: Rng> Iterator for Generator<'a, T, R> { From 62b517772a11e2ff5accffd03e1832535f9bdc1d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 12:41:31 -0500 Subject: [PATCH 37/76] Fallout: add phantom data to the type inferencer --- src/librustc/middle/infer/type_variable.rs | 5 +++-- src/librustc/middle/infer/unify.rs | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/librustc/middle/infer/type_variable.rs b/src/librustc/middle/infer/type_variable.rs index 4b9718b4f6ce7..a856137af090a 100644 --- a/src/librustc/middle/infer/type_variable.rs +++ b/src/librustc/middle/infer/type_variable.rs @@ -14,6 +14,7 @@ use self::UndoEntry::*; use middle::ty::{self, Ty}; use std::cmp::min; +use std::marker::PhantomData; use std::mem; use std::u32; use util::snapshot_vec as sv; @@ -42,7 +43,7 @@ enum UndoEntry { Relate(ty::TyVid, ty::TyVid), } -struct Delegate<'tcx>; +struct Delegate<'tcx>(PhantomData<&'tcx ()>); type Relation = (RelationDir, ty::TyVid); @@ -64,7 +65,7 @@ impl RelationDir { impl<'tcx> TypeVariableTable<'tcx> { pub fn new() -> TypeVariableTable<'tcx> { - TypeVariableTable { values: sv::SnapshotVec::new(Delegate) } + TypeVariableTable { values: sv::SnapshotVec::new(Delegate(PhantomData)) } } fn relations<'a>(&'a mut self, a: ty::TyVid) -> &'a mut Vec { diff --git a/src/librustc/middle/infer/unify.rs b/src/librustc/middle/infer/unify.rs index 923f7d2d4ef35..07cb316c5bfc2 100644 --- a/src/librustc/middle/infer/unify.rs +++ b/src/librustc/middle/infer/unify.rs @@ -18,6 +18,7 @@ use middle::infer::{uok, ures}; use middle::infer::InferCtxt; use std::cell::RefCell; use std::fmt::Debug; +use std::marker::PhantomData; use syntax::ast; use util::snapshot_vec as sv; @@ -79,7 +80,7 @@ pub struct UnificationTable { /// made during the snapshot may either be *committed* or *rolled back*. pub struct Snapshot { // Link snapshot to the key type `K` of the table. - marker: marker::CovariantType, + marker: marker::PhantomData, snapshot: sv::Snapshot, } @@ -92,7 +93,7 @@ pub struct Node { } #[derive(Copy)] -pub struct Delegate; +pub struct Delegate(PhantomData); // We can't use V:LatticeValue, much as I would like to, // because frequently the pattern is that V=Option for some @@ -102,14 +103,14 @@ pub struct Delegate; impl UnificationTable { pub fn new() -> UnificationTable { UnificationTable { - values: sv::SnapshotVec::new(Delegate), + values: sv::SnapshotVec::new(Delegate(PhantomData)), } } /// Starts a new snapshot. Each snapshot must be either /// rolled back or committed in a "LIFO" (stack) order. pub fn snapshot(&mut self) -> Snapshot { - Snapshot { marker: marker::CovariantType::, + Snapshot { marker: marker::PhantomData::, snapshot: self.values.start_snapshot() } } From 1ed58428297611f60a6b5c7cf7024a4cd25b672c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 12:44:06 -0500 Subject: [PATCH 38/76] Fallout: extend thread with phantomdata for `'a` lifetime --- src/libstd/thread.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index 3137d779c4071..2d825a0f4550b 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -153,7 +153,7 @@ use any::Any; use cell::UnsafeCell; use fmt; use io; -use marker; +use marker::{PhantomData, Send, Sync}; use old_io::stdio; use rt::{self, unwind}; use sync::{Mutex, Condvar, Arc}; @@ -260,7 +260,7 @@ impl Builder { T: Send + 'a, F: FnOnce() -> T, F: Send + 'a { self.spawn_inner(Thunk::new(f)).map(|inner| { - JoinGuard { inner: inner, _marker: marker::CovariantType } + JoinGuard { inner: inner, _marker: PhantomData } }) } @@ -642,7 +642,7 @@ impl Drop for JoinHandle { #[stable(feature = "rust1", since = "1.0.0")] pub struct JoinGuard<'a, T: 'a> { inner: JoinInner, - _marker: marker::CovariantType<&'a T>, + _marker: PhantomData<&'a T>, } #[stable(feature = "rust1", since = "1.0.0")] From 9e0bb528a42a9c963d1616a86e0eb8fb80b34be8 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 12:45:06 -0500 Subject: [PATCH 39/76] Fallout: add phantomdata for 'a in path --- src/libstd/path.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 1d992668900f0..e3650537a63ad 100755 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -143,6 +143,7 @@ mod platform { use super::Prefix; use core::prelude::*; use ffi::OsStr; + use std::marker::PhantomData; #[inline] pub fn is_sep_byte(b: u8) -> bool { From ae7c534d042bb37e7e22cefabaa81b304638bc0b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 12:46:24 -0500 Subject: [PATCH 40/76] Fallout: port hashmap to use Unique --- src/libstd/collections/hash/table.rs | 62 +++++++++++++++++----------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 0bb6bd4cf356a..aaf4cf4c445f1 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -23,8 +23,8 @@ use num::{Int, UnsignedInt}; use ops::{Deref, DerefMut, Drop}; use option::Option; use option::Option::{Some, None}; -use ptr::{self, PtrExt, copy_nonoverlapping_memory, zero_memory}; -use rt::heap::{allocate, deallocate}; +use ptr::{self, PtrExt, copy_nonoverlapping_memory, Unique, zero_memory}; +use rt::heap::{allocate, deallocate, EMPTY}; use collections::hash_state::HashState; const EMPTY_BUCKET: u64 = 0u64; @@ -69,10 +69,11 @@ const EMPTY_BUCKET: u64 = 0u64; pub struct RawTable { capacity: usize, size: usize, - hashes: *mut u64, + hashes: Unique, + // Because K/V do not appear directly in any of the types in the struct, // inform rustc that in fact instances of K and V are reachable from here. - marker: marker::CovariantType<(K,V)>, + marker: marker::PhantomData<(K,V)>, } unsafe impl Send for RawTable {} @@ -81,7 +82,8 @@ unsafe impl Sync for RawTable {} struct RawBucket { hash: *mut u64, key: *mut K, - val: *mut V + val: *mut V, + _marker: marker::PhantomData<(K,V)>, } impl Copy for RawBucket {} @@ -170,11 +172,12 @@ fn can_alias_safehash_as_u64() { } impl RawBucket { - unsafe fn offset(self, count: int) -> RawBucket { + unsafe fn offset(self, count: isize) -> RawBucket { RawBucket { hash: self.hash.offset(count), key: self.key.offset(count), val: self.val.offset(count), + _marker: marker::PhantomData, } } } @@ -567,10 +570,11 @@ impl RawTable { return RawTable { size: 0, capacity: 0, - hashes: ptr::null_mut(), - marker: marker::CovariantType, + hashes: Unique::new(EMPTY as *mut u64), + marker: marker::PhantomData, }; } + // No need for `checked_mul` before a more restrictive check performed // later in this method. let hashes_size = capacity * size_of::(); @@ -606,8 +610,8 @@ impl RawTable { RawTable { capacity: capacity, size: 0, - hashes: hashes, - marker: marker::CovariantType, + hashes: Unique::new(hashes), + marker: marker::PhantomData, } } @@ -615,16 +619,17 @@ impl RawTable { let hashes_size = self.capacity * size_of::(); let keys_size = self.capacity * size_of::(); - let buffer = self.hashes as *mut u8; + let buffer = *self.hashes as *mut u8; let (keys_offset, vals_offset) = calculate_offsets(hashes_size, keys_size, min_align_of::(), min_align_of::()); unsafe { RawBucket { - hash: self.hashes, + hash: *self.hashes, key: buffer.offset(keys_offset as isize) as *mut K, - val: buffer.offset(vals_offset as isize) as *mut V + val: buffer.offset(vals_offset as isize) as *mut V, + _marker: marker::PhantomData, } } } @@ -634,7 +639,7 @@ impl RawTable { pub fn new(capacity: usize) -> RawTable { unsafe { let ret = RawTable::new_uninitialized(capacity); - zero_memory(ret.hashes, capacity); + zero_memory(*ret.hashes, capacity); ret } } @@ -656,7 +661,7 @@ impl RawTable { hashes_end: unsafe { self.hashes.offset(self.capacity as isize) }, - marker: marker::ContravariantLifetime, + marker: marker::PhantomData, } } @@ -681,7 +686,7 @@ impl RawTable { iter: RawBuckets { raw: raw, hashes_end: hashes_end, - marker: marker::ContravariantLifetime, + marker: marker::PhantomData, }, table: self, } @@ -694,7 +699,7 @@ impl RawTable { iter: RawBuckets { raw: raw, hashes_end: hashes_end, - marker: marker::ContravariantLifetime::<'static>, + marker: marker::PhantomData, }, table: self, } @@ -708,7 +713,7 @@ impl RawTable { raw: raw_bucket.offset(self.capacity as isize), hashes_end: raw_bucket.hash, elems_left: self.size, - marker: marker::ContravariantLifetime, + marker: marker::PhantomData, } } } @@ -718,7 +723,13 @@ impl RawTable { struct RawBuckets<'a, K, V> { raw: RawBucket, hashes_end: *mut u64, - marker: marker::ContravariantLifetime<'a>, + + // Strictly speaking, this should be &'a (K,V), but that would + // require that K:'a, and we often use RawBuckets<'static...> for + // move iterations, so that messes up a lot of other things. So + // just use `&'a (K,V)` as this is not a publicly exposed type + // anyway. + marker: marker::PhantomData<&'a ()>, } // FIXME(#19839) Remove in favor of `#[derive(Clone)]` @@ -727,7 +738,7 @@ impl<'a, K, V> Clone for RawBuckets<'a, K, V> { RawBuckets { raw: self.raw, hashes_end: self.hashes_end, - marker: marker::ContravariantLifetime, + marker: marker::PhantomData, } } } @@ -759,7 +770,11 @@ struct RevMoveBuckets<'a, K, V> { raw: RawBucket, hashes_end: *mut u64, elems_left: usize, - marker: marker::ContravariantLifetime<'a>, + + // As above, `&'a (K,V)` would seem better, but we often use + // 'static for the lifetime, and this is not a publicly exposed + // type. + marker: marker::PhantomData<&'a ()>, } impl<'a, K, V> Iterator for RevMoveBuckets<'a, K, V> { @@ -966,9 +981,10 @@ impl Clone for RawTable { #[unsafe_destructor] impl Drop for RawTable { fn drop(&mut self) { - if self.hashes.is_null() { + if self.capacity == 0 { return; } + // This is done in reverse because we've likely partially taken // some elements out with `.into_iter()` from the front. // Check if the size is 0, so we don't do a useless scan when @@ -986,7 +1002,7 @@ impl Drop for RawTable { vals_size, min_align_of::()); unsafe { - deallocate(self.hashes as *mut u8, size, align); + deallocate(*self.hashes as *mut u8, size, align); // Remember how everything was allocated out of one buffer // during initialization? We only need one call to free here. } From 6f2a1c946744dd6c1de7a1c556cb1333592dec62 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 12:46:40 -0500 Subject: [PATCH 41/76] Fallout: add phantomdata to hash --- src/libstd/collections/hash/state.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libstd/collections/hash/state.rs b/src/libstd/collections/hash/state.rs index 79e01304fb8c0..7e6dd45b51e48 100644 --- a/src/libstd/collections/hash/state.rs +++ b/src/libstd/collections/hash/state.rs @@ -11,6 +11,7 @@ use clone::Clone; use default::Default; use hash; +use marker; /// A trait representing stateful hashes which can be used to hash keys in a /// `HashMap`. @@ -37,7 +38,7 @@ pub trait HashState { /// /// This struct has is 0-sized and does not need construction. #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")] -pub struct DefaultState; +pub struct DefaultState(marker::PhantomData); impl HashState for DefaultState { type Hasher = H; @@ -45,9 +46,9 @@ impl HashState for DefaultState { } impl Clone for DefaultState { - fn clone(&self) -> DefaultState { DefaultState } + fn clone(&self) -> DefaultState { DefaultState(marker::PhantomData) } } impl Default for DefaultState { - fn default() -> DefaultState { DefaultState } + fn default() -> DefaultState { DefaultState(marker::PhantomData) } } From df76442c99635e176f70d2e7977317a871b8f906 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Feb 2015 12:49:10 -0500 Subject: [PATCH 42/76] Fallout: Accepter trait needs phantomdata. This seems like it should be migrated to an associated type anyway. --- src/libstd/old_io/mod.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libstd/old_io/mod.rs b/src/libstd/old_io/mod.rs index 9655da92e5697..8b9eb44066f1d 100644 --- a/src/libstd/old_io/mod.rs +++ b/src/libstd/old_io/mod.rs @@ -252,7 +252,7 @@ use error::Error; use fmt; use isize; use iter::{Iterator, IteratorExt}; -use marker::Sized; +use marker::{PhantomFn, Sized}; use mem::transmute; use ops::FnOnce; use option::Option; @@ -1572,7 +1572,9 @@ pub trait Seek { /// connections. /// /// Doing so produces some sort of Acceptor. -pub trait Listener> { +pub trait Listener> + : PhantomFn // FIXME should be an assoc type anyhow +{ /// Spin up the listener and start queuing incoming connections /// /// # Error From d179bb56b0111bb2423cbde9633664e251b02530 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 13 Feb 2015 12:49:03 -0500 Subject: [PATCH 43/76] Add regression test for #20533. Fixes #20533. --- src/test/compile-fail/variance-issue-20533.rs | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/test/compile-fail/variance-issue-20533.rs diff --git a/src/test/compile-fail/variance-issue-20533.rs b/src/test/compile-fail/variance-issue-20533.rs new file mode 100644 index 0000000000000..0254f56bd1a94 --- /dev/null +++ b/src/test/compile-fail/variance-issue-20533.rs @@ -0,0 +1,54 @@ +// Copyright 2015 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. + +// Regression test for issue #20533. At some point, only 1 out of the +// 3 errors below were being reported. + +use std::marker::PhantomData; + +fn foo<'a, T>(_x: &'a T) -> PhantomData<&'a ()> { + PhantomData +} + +struct Wrap(T); + +fn bar<'a, T>(_x: &'a T) -> Wrap> { + Wrap(PhantomData) +} + +struct Baked<'a>(PhantomData<&'a ()>); + +fn baz<'a, T>(_x: &'a T) -> Baked<'a> { + Baked(PhantomData) +} + +struct AffineU32(u32); + +fn main() { + { + let a = AffineU32(1_u32); + let x = foo(&a); + drop(a); //~ ERROR cannot move out of `a` + drop(x); + } + { + let a = AffineU32(1_u32); + let x = bar(&a); + drop(a); //~ ERROR cannot move out of `a` + drop(x); + } + { + let a = AffineU32(1_u32); + let x = baz(&a); + drop(a); //~ ERROR cannot move out of `a` + drop(x); + } +} + From e8cb11c7e39d896a6d361e86470cf3dcae8856a9 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 18 Feb 2015 10:20:01 -0500 Subject: [PATCH 44/76] Missing test. --- .../regions-close-object-into-object-5.rs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/test/compile-fail/regions-close-object-into-object-5.rs diff --git a/src/test/compile-fail/regions-close-object-into-object-5.rs b/src/test/compile-fail/regions-close-object-into-object-5.rs new file mode 100644 index 0000000000000..05c6c6d9f9e02 --- /dev/null +++ b/src/test/compile-fail/regions-close-object-into-object-5.rs @@ -0,0 +1,32 @@ +// Copyright 2014 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. + +#![feature(box_syntax)] +#![allow(warnings)] + +use std::marker::MarkerTrait; + +trait A +{ + fn get(&self) -> T { panic!() } +} + +struct B<'a, T>(&'a (A+'a)); + +trait X : MarkerTrait {} + +impl<'a, T> X for B<'a, T> {} + +fn f<'a, T, U>(v: Box+'static>) -> Box { + box B(&*v) as Box //~ ERROR the parameter type `T` may not live long enough +} + +fn main() {} + From f83e23ad7c464c242c2d7ace7212d323980b2bca Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 17 Feb 2015 20:48:07 -0800 Subject: [PATCH 45/76] std: Stabilize the `hash` module This commit is an implementation of [RFC 823][rfc] which is another pass over the `std::hash` module for stabilization. The contents of the module were not entirely marked stable, but some portions which remained quite similar to the previous incarnation are now marked `#[stable]`. Specifically: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0823-hash-simplification.md * `std::hash` is now stable (the name) * `Hash` is now stable * `Hash::hash` is now stable * `Hasher` is now stable * `SipHasher` is now stable * `SipHasher::new` and `new_with_keys` are now stable * `Hasher for SipHasher` is now stable * Many `Hash` implementations are now stable All other portions of the `hash` module remain `#[unstable]` as they are less commonly used and were recently redesigned. This commit is a breaking change due to the modifications to the `std::hash` API and more details can be found on the [RFC][rfc]. Closes #22467 [breaking-change] --- src/liballoc/arc.rs | 8 + src/liballoc/boxed.rs | 25 +- src/liballoc/lib.rs | 1 - src/liballoc/rc.rs | 12 +- src/libcollections/bit.rs | 21 + src/libcollections/btree/map.rs | 10 + src/libcollections/dlist.rs | 15 +- src/libcollections/lib.rs | 1 - src/libcollections/ring_buf.rs | 14 +- src/libcollections/string.rs | 9 + src/libcollections/vec.rs | 9 + src/libcollections/vec_map.rs | 19 +- src/libcore/array.rs | 12 +- src/libcore/hash/mod.rs | 494 +++- src/libcore/hash/sip.rs | 45 +- src/libcoretest/hash/mod.rs | 24 +- src/librustc/lint/mod.rs | 8 + src/librustc/metadata/encoder.rs | 42 + src/librustc/middle/ty.rs | 17 +- src/librustc/util/common.rs | 93 +- src/librustc/util/nodemap.rs | 28 +- src/librustc/util/ppaux.rs | 19 +- src/librustc_borrowck/lib.rs | 1 - src/librustc_llvm/lib.rs | 1 - src/librustc_resolve/lib.rs | 1 - src/librustc_trans/lib.rs | 1 - src/librustdoc/lib.rs | 1 - src/libserialize/collection_impls.rs | 76 +- src/libserialize/lib.rs | 1 - src/libstd/collections/hash/map.rs | 128 +- src/libstd/collections/hash/map_stage0.rs | 2329 +++++++++++++++++++ src/libstd/collections/hash/mod.rs | 8 + src/libstd/collections/hash/set.rs | 121 +- src/libstd/collections/hash/set_stage0.rs | 1251 ++++++++++ src/libstd/collections/hash/table.rs | 17 + src/libstd/ffi/os_str.rs | 21 +- src/libstd/net/addr.rs | 16 + src/libstd/net/ip.rs | 16 + src/libstd/old_path/posix.rs | 9 + src/libstd/old_path/windows.rs | 16 + src/libstd/sys/common/wtf8.rs | 29 +- src/libstd/sys/unix/process.rs | 249 ++ src/libstd/sys/unix/process2.rs | 1 - src/libsyntax/ext/deriving/hash.rs | 25 +- src/libsyntax/lib.rs | 1 - src/libsyntax/ptr.rs | 7 + src/libsyntax/util/interner.rs | 76 +- src/libtest/lib.rs | 1 - src/libtest/stats.rs | 4 +- src/test/bench/core-set.rs | 3 +- src/test/compile-fail/issue-21160.rs | 2 +- src/test/run-pass/deriving-hash.rs | 2 +- src/test/run-pass/deriving-meta-multiple.rs | 2 +- src/test/run-pass/deriving-meta.rs | 2 +- 54 files changed, 4988 insertions(+), 356 deletions(-) create mode 100644 src/libstd/collections/hash/map_stage0.rs create mode 100644 src/libstd/collections/hash/set_stage0.rs diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 3830d7fe29532..343ede4e2cf45 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -605,11 +605,19 @@ impl Default for Arc { fn default() -> Arc { Arc::new(Default::default()) } } +#[cfg(stage0)] impl> Hash for Arc { fn hash(&self, state: &mut H) { (**self).hash(state) } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for Arc { + fn hash(&self, state: &mut H) { + (**self).hash(state) + } +} #[cfg(test)] mod tests { diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 340a8d59612f2..a3516bd667b7a 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -10,13 +10,14 @@ //! A pointer type for heap allocation. //! -//! `Box`, casually referred to as a 'box', provides the simplest form of heap allocation in -//! Rust. Boxes provide ownership for this allocation, and drop their contents when they go out of -//! scope. +//! `Box`, casually referred to as a 'box', provides the simplest form of +//! heap allocation in Rust. Boxes provide ownership for this allocation, and +//! drop their contents when they go out of scope. //! -//! Boxes are useful in two situations: recursive data structures, and occasionally when returning -//! data. [The Pointer chapter of the Book](../../../book/pointers.html#best-practices-1) explains -//! these cases in detail. +//! Boxes are useful in two situations: recursive data structures, and +//! occasionally when returning data. [The Pointer chapter of the +//! Book](../../../book/pointers.html#best-practices-1) explains these cases in +//! detail. //! //! # Examples //! @@ -58,8 +59,8 @@ use core::ops::{Deref, DerefMut}; use core::ptr::Unique; use core::raw::TraitObject; -/// A value that represents the heap. This is the default place that the `box` keyword allocates -/// into when no place is supplied. +/// A value that represents the heap. This is the default place that the `box` +/// keyword allocates into when no place is supplied. /// /// The following two examples are equivalent: /// @@ -219,12 +220,20 @@ impl Ord for Box { #[stable(feature = "rust1", since = "1.0.0")] impl Eq for Box {} +#[cfg(stage0)] impl> Hash for Box { #[inline] fn hash(&self, state: &mut S) { (**self).hash(state); } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for Box { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } +} /// Extension methods for an owning `Any` trait object. #[unstable(feature = "alloc", diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index b3c2638f3ae28..bc349ebebdeed 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -73,7 +73,6 @@ #![feature(unboxed_closures)] #![feature(unsafe_no_drop_flag)] #![feature(core)] -#![feature(hash)] #![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")), feature(libc))] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index f361c36ec8fa7..65513465dd2a9 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -150,7 +150,7 @@ use core::clone::Clone; use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering}; use core::default::Default; use core::fmt; -use core::hash::{self, Hash}; +use core::hash::{Hasher, Hash}; use core::marker; use core::mem::{transmute, min_align_of, size_of, forget}; use core::nonzero::NonZero; @@ -599,12 +599,20 @@ impl Ord for Rc { } // FIXME (#18248) Make `T` `Sized?` -impl> Hash for Rc { +#[cfg(stage0)] +impl> Hash for Rc { #[inline] fn hash(&self, state: &mut S) { (**self).hash(state); } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for Rc { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } +} #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for Rc { diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 0b762788b208a..375684865dd10 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -984,6 +984,7 @@ impl fmt::Debug for Bitv { } #[stable(feature = "rust1", since = "1.0.0")] +#[cfg(stage0)] impl hash::Hash for Bitv { fn hash(&self, state: &mut S) { self.nbits.hash(state); @@ -992,6 +993,16 @@ impl hash::Hash for Bitv { } } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl hash::Hash for Bitv { + fn hash(&self, state: &mut H) { + self.nbits.hash(state); + for elem in self.blocks() { + elem.hash(state); + } + } +} #[stable(feature = "rust1", since = "1.0.0")] impl cmp::PartialEq for Bitv { @@ -1756,6 +1767,7 @@ impl fmt::Debug for BitvSet { } } +#[cfg(stage0)] impl hash::Hash for BitvSet { fn hash(&self, state: &mut S) { for pos in self { @@ -1763,6 +1775,15 @@ impl hash::Hash for BitvSet { } } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl hash::Hash for BitvSet { + fn hash(&self, state: &mut H) { + for pos in self { + pos.hash(state); + } + } +} /// An iterator for `BitvSet`. #[derive(Clone)] diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 747211e923859..73d2af28a046a 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -843,6 +843,7 @@ impl Extend<(K, V)> for BTreeMap { } } +#[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] impl, V: Hash> Hash for BTreeMap { fn hash(&self, state: &mut S) { @@ -851,6 +852,15 @@ impl, V: Hash> Hash for BTreeMap { } } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for BTreeMap { + fn hash(&self, state: &mut H) { + for elt in self { + elt.hash(state); + } + } +} #[stable(feature = "rust1", since = "1.0.0")] impl Default for BTreeMap { diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index eb1bf93c0aafc..bdcb66b27aa58 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -27,7 +27,9 @@ use alloc::boxed::Box; use core::cmp::Ordering; use core::default::Default; use core::fmt; -use core::hash::{Writer, Hasher, Hash}; +use core::hash::{Hasher, Hash}; +#[cfg(stage0)] +use core::hash::Writer; use core::iter::{self, FromIterator, IntoIterator}; use core::mem; use core::ptr; @@ -926,6 +928,7 @@ impl fmt::Debug for DList { } #[stable(feature = "rust1", since = "1.0.0")] +#[cfg(stage0)] impl> Hash for DList { fn hash(&self, state: &mut S) { self.len().hash(state); @@ -934,6 +937,16 @@ impl> Hash for DList { } } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl Hash for DList { + fn hash(&self, state: &mut H) { + self.len().hash(state); + for elt in self { + elt.hash(state); + } + } +} #[cfg(test)] mod tests { diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index cacbf3bce80f0..06f7e825a1466 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -26,7 +26,6 @@ #![feature(box_syntax)] #![feature(box_patterns)] #![feature(core)] -#![feature(hash)] #![feature(staged_api)] #![feature(unboxed_closures)] #![feature(unicode)] diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs index 6dcdb21f8000b..c241b096b39d1 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/ring_buf.rs @@ -31,7 +31,8 @@ use core::ops::{Index, IndexMut}; use core::ptr; use core::raw::Slice as RawSlice; -use core::hash::{Writer, Hash, Hasher}; +use core::hash::{Hash, Hasher}; +#[cfg(stage0)] use core::hash::Writer; use core::cmp; use alloc::heap; @@ -1667,6 +1668,7 @@ impl Ord for RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] +#[cfg(stage0)] impl> Hash for RingBuf { fn hash(&self, state: &mut S) { self.len().hash(state); @@ -1675,6 +1677,16 @@ impl> Hash for RingBuf { } } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl Hash for RingBuf { + fn hash(&self, state: &mut H) { + self.len().hash(state); + for elt in self { + elt.hash(state); + } + } +} #[stable(feature = "rust1", since = "1.0.0")] impl Index for RingBuf { diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 69fd28d172368..6204c4427b516 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -833,12 +833,21 @@ impl fmt::Debug for String { } #[unstable(feature = "collections", reason = "waiting on Hash stabilization")] +#[cfg(stage0)] impl hash::Hash for String { #[inline] fn hash(&self, hasher: &mut H) { (**self).hash(hasher) } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl hash::Hash for String { + #[inline] + fn hash(&self, hasher: &mut H) { + (**self).hash(hasher) + } +} #[unstable(feature = "collections", reason = "recent addition, needs more experience")] diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index bde733644b5b5..6bc9ff52f9477 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1302,12 +1302,21 @@ impl Clone for Vec { } } +#[cfg(stage0)] impl> Hash for Vec { #[inline] fn hash(&self, state: &mut S) { Hash::hash(&**self, state) } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl Hash for Vec { + #[inline] + fn hash(&self, state: &mut H) { + Hash::hash(&**self, state) + } +} #[stable(feature = "rust1", since = "1.0.0")] impl Index for Vec { diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 82ccfd0614fd5..c271cb052abd6 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -20,7 +20,8 @@ use core::prelude::*; use core::cmp::Ordering; use core::default::Default; use core::fmt; -use core::hash::{Hash, Writer, Hasher}; +use core::hash::{Hash, Hasher}; +#[cfg(stage0)] use core::hash::Writer; use core::iter::{Enumerate, FilterMap, Map, FromIterator, IntoIterator}; use core::iter; use core::mem::replace; @@ -99,6 +100,7 @@ impl Default for VecMap { fn default() -> VecMap { VecMap::new() } } +#[stable(feature = "rust1", since = "1.0.0")] impl Clone for VecMap { #[inline] fn clone(&self) -> VecMap { @@ -111,6 +113,7 @@ impl Clone for VecMap { } } +#[cfg(stage0)] impl> Hash for VecMap { fn hash(&self, state: &mut S) { // In order to not traverse the `VecMap` twice, count the elements @@ -123,6 +126,20 @@ impl> Hash for VecMap { count.hash(state); } } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(stage0))] +impl Hash for VecMap { + fn hash(&self, state: &mut H) { + // In order to not traverse the `VecMap` twice, count the elements + // during iteration. + let mut count: usize = 0; + for elt in self { + elt.hash(state); + count += 1; + } + count.hash(state); + } +} impl VecMap { /// Creates an empty `VecMap`. diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 838ca4e478b72..b2bb5ee7999d8 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -17,7 +17,7 @@ use clone::Clone; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; use fmt; -use hash::{Hash, Hasher, self}; +use hash::{Hash, self}; use iter::IntoIterator; use marker::Copy; use ops::Deref; @@ -35,11 +35,19 @@ macro_rules! array_impls { } } - impl> Hash for [T; $N] { + #[cfg(stage0)] + impl> Hash for [T; $N] { fn hash(&self, state: &mut S) { Hash::hash(&self[], state) } } + #[cfg(not(stage0))] + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for [T; $N] { + fn hash(&self, state: &mut H) { + Hash::hash(&self[], state) + } + } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for [T; $N] { diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index a5d2618eff948..b9a5122dd9c00 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -35,7 +35,7 @@ //! the trait `Hash`: //! //! ```rust -//! use std::hash::{hash, Hash, Hasher, Writer, SipHasher}; +//! use std::hash::{hash, Hash, Hasher, SipHasher}; //! //! struct Person { //! id: uint, @@ -43,8 +43,8 @@ //! phone: u64, //! } //! -//! impl Hash for Person { -//! fn hash(&self, state: &mut H) { +//! impl Hash for Person { +//! fn hash(&self, state: &mut H) { //! self.id.hash(state); //! self.phone.hash(state); //! } @@ -56,15 +56,11 @@ //! assert_eq!(hash::<_, SipHasher>(&person1), hash::<_, SipHasher>(&person2)); //! ``` -#![unstable(feature = "hash", - reason = "module was recently redesigned")] +#![stable(feature = "rust1", since = "1.0.0")] -use prelude::*; - -use borrow::{Cow, ToOwned}; use default::Default; +use marker::Sized; use mem; -use num::Int; pub use self::sip::SipHasher; @@ -76,22 +72,123 @@ mod sip; /// to compute the hash. Specific implementations of this trait may specialize /// for particular instances of `H` in order to be able to optimize the hashing /// behavior. +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Hash { + /// Feeds this value into the state given, updating the hasher as necessary. + #[stable(feature = "rust1", since = "1.0.0")] + fn hash(&self, state: &mut H); + + /// Feeds a slice of this type into the state provided. + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn hash_slice(data: &[Self], state: &mut H) where Self: Sized { + for piece in data { + piece.hash(state); + } + } +} + +/// A hashable type. +/// +/// The `H` type parameter is an abstract hash state that is used by the `Hash` +/// to compute the hash. Specific implementations of this trait may specialize +/// for particular instances of `H` in order to be able to optimize the hashing +/// behavior. +#[cfg(stage0)] pub trait Hash { /// Feeds this value into the state given, updating the hasher as necessary. fn hash(&self, state: &mut H); } /// A trait which represents the ability to hash an arbitrary stream of bytes. +#[stable(feature = "rust1", since = "1.0.0")] pub trait Hasher { /// Result type of one run of hashing generated by this hasher. + #[cfg(stage0)] type Output; /// Resets this hasher back to its initial state (as if it were just /// created). + #[cfg(stage0)] fn reset(&mut self); /// Completes a round of hashing, producing the output hash generated. + #[cfg(stage0)] fn finish(&self) -> Self::Output; + + /// Completes a round of hashing, producing the output hash generated. + #[cfg(not(stage0))] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn finish(&self) -> u64; + + /// Writes some data into this `Hasher` + #[cfg(not(stage0))] + #[stable(feature = "rust1", since = "1.0.0")] + fn write(&mut self, bytes: &[u8]); + + /// Write a single `u8` into this hasher + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_u8(&mut self, i: u8) { self.write(&[i]) } + /// Write a single `u16` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_u16(&mut self, i: u16) { + self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) }) + } + /// Write a single `u32` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_u32(&mut self, i: u32) { + self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) }) + } + /// Write a single `u64` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_u64(&mut self, i: u64) { + self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) }) + } + /// Write a single `usize` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_usize(&mut self, i: usize) { + if cfg!(target_pointer_size = "32") { + self.write_u32(i as u32) + } else { + self.write_u64(i as u64) + } + } + + /// Write a single `i8` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_i8(&mut self, i: i8) { self.write_u8(i as u8) } + /// Write a single `i16` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_i16(&mut self, i: i16) { self.write_u16(i as u16) } + /// Write a single `i32` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_i32(&mut self, i: i32) { self.write_u32(i as u32) } + /// Write a single `i64` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_i64(&mut self, i: i64) { self.write_u64(i as u64) } + /// Write a single `isize` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_isize(&mut self, i: isize) { self.write_usize(i as usize) } } /// A common bound on the `Hasher` parameter to `Hash` implementations in order @@ -99,6 +196,7 @@ pub trait Hasher { #[unstable(feature = "hash", reason = "this trait will likely be replaced by io::Writer")] #[allow(missing_docs)] +#[cfg(stage0)] pub trait Writer { fn write(&mut self, bytes: &[u8]); } @@ -107,148 +205,312 @@ pub trait Writer { /// /// The specified value will be hashed with this hasher and then the resulting /// hash will be returned. +#[cfg(stage0)] pub fn hash, H: Hasher + Default>(value: &T) -> H::Output { let mut h: H = Default::default(); value.hash(&mut h); h.finish() } +/// Hash a value with the default SipHasher algorithm (two initial keys of 0). +/// +/// The specified value will be hashed with this hasher and then the resulting +/// hash will be returned. +#[cfg(not(stage0))] +#[unstable(feature = "hash", reason = "module was recently redesigned")] +pub fn hash(value: &T) -> u64 { + let mut h: H = Default::default(); + value.hash(&mut h); + h.finish() +} + ////////////////////////////////////////////////////////////////////////////// -macro_rules! impl_hash { - ($ty:ident, $uty:ident) => { - impl Hash for $ty { - #[inline] - fn hash(&self, state: &mut S) { - let a: [u8; ::$ty::BYTES] = unsafe { - mem::transmute((*self as $uty).to_le() as $ty) - }; - state.write(&a) +#[cfg(stage0)] +mod impls { + use prelude::*; + + use borrow::{Cow, ToOwned}; + use mem; + use num::Int; + use super::*; + + macro_rules! impl_hash { + ($ty:ident, $uty:ident) => { + impl Hash for $ty { + #[inline] + fn hash(&self, state: &mut S) { + let a: [u8; ::$ty::BYTES] = unsafe { + mem::transmute((*self as $uty).to_le() as $ty) + }; + state.write(&a) + } } } } -} -impl_hash! { u8, u8 } -impl_hash! { u16, u16 } -impl_hash! { u32, u32 } -impl_hash! { u64, u64 } -impl_hash! { uint, uint } -impl_hash! { i8, u8 } -impl_hash! { i16, u16 } -impl_hash! { i32, u32 } -impl_hash! { i64, u64 } -impl_hash! { int, uint } - -impl Hash for bool { - #[inline] - fn hash(&self, state: &mut S) { - (*self as u8).hash(state); + impl_hash! { u8, u8 } + impl_hash! { u16, u16 } + impl_hash! { u32, u32 } + impl_hash! { u64, u64 } + impl_hash! { uint, uint } + impl_hash! { i8, u8 } + impl_hash! { i16, u16 } + impl_hash! { i32, u32 } + impl_hash! { i64, u64 } + impl_hash! { int, uint } + + impl Hash for bool { + #[inline] + fn hash(&self, state: &mut S) { + (*self as u8).hash(state); + } } -} -impl Hash for char { - #[inline] - fn hash(&self, state: &mut S) { - (*self as u32).hash(state); + impl Hash for char { + #[inline] + fn hash(&self, state: &mut S) { + (*self as u32).hash(state); + } } -} -impl Hash for str { - #[inline] - fn hash(&self, state: &mut S) { - state.write(self.as_bytes()); - 0xffu8.hash(state) + impl Hash for str { + #[inline] + fn hash(&self, state: &mut S) { + state.write(self.as_bytes()); + 0xffu8.hash(state) + } } -} -macro_rules! impl_hash_tuple { - () => ( - impl Hash for () { - #[inline] - fn hash(&self, _state: &mut S) {} - } - ); - - ( $($name:ident)+) => ( - impl),*> Hash for ($($name,)*) { - #[inline] - #[allow(non_snake_case)] - fn hash(&self, state: &mut S) { - match *self { - ($(ref $name,)*) => { - $( - $name.hash(state); - )* + macro_rules! impl_hash_tuple { + () => ( + impl Hash for () { + #[inline] + fn hash(&self, _state: &mut S) {} + } + ); + + ( $($name:ident)+) => ( + impl),*> Hash for ($($name,)*) { + #[inline] + #[allow(non_snake_case)] + fn hash(&self, state: &mut S) { + match *self { + ($(ref $name,)*) => { + $( + $name.hash(state); + )* + } } } } + ); + } + + impl_hash_tuple! {} + impl_hash_tuple! { A } + impl_hash_tuple! { A B } + impl_hash_tuple! { A B C } + impl_hash_tuple! { A B C D } + impl_hash_tuple! { A B C D E } + impl_hash_tuple! { A B C D E F } + impl_hash_tuple! { A B C D E F G } + impl_hash_tuple! { A B C D E F G H } + impl_hash_tuple! { A B C D E F G H I } + impl_hash_tuple! { A B C D E F G H I J } + impl_hash_tuple! { A B C D E F G H I J K } + impl_hash_tuple! { A B C D E F G H I J K L } + + impl> Hash for [T] { + #[inline] + fn hash(&self, state: &mut S) { + self.len().hash(state); + for elt in self { + elt.hash(state); + } } - ); -} + } -impl_hash_tuple! {} -impl_hash_tuple! { A } -impl_hash_tuple! { A B } -impl_hash_tuple! { A B C } -impl_hash_tuple! { A B C D } -impl_hash_tuple! { A B C D E } -impl_hash_tuple! { A B C D E F } -impl_hash_tuple! { A B C D E F G } -impl_hash_tuple! { A B C D E F G H } -impl_hash_tuple! { A B C D E F G H I } -impl_hash_tuple! { A B C D E F G H I J } -impl_hash_tuple! { A B C D E F G H I J K } -impl_hash_tuple! { A B C D E F G H I J K L } - -impl> Hash for [T] { - #[inline] - fn hash(&self, state: &mut S) { - self.len().hash(state); - for elt in self { - elt.hash(state); + + impl<'a, S: Hasher, T: ?Sized + Hash> Hash for &'a T { + #[inline] + fn hash(&self, state: &mut S) { + (**self).hash(state); } } -} + impl<'a, S: Hasher, T: ?Sized + Hash> Hash for &'a mut T { + #[inline] + fn hash(&self, state: &mut S) { + (**self).hash(state); + } + } -impl<'a, S: Hasher, T: ?Sized + Hash> Hash for &'a T { - #[inline] - fn hash(&self, state: &mut S) { - (**self).hash(state); + impl Hash for *const T { + #[inline] + fn hash(&self, state: &mut S) { + // NB: raw-pointer Hash does _not_ dereference + // to the target; it just gives you the pointer-bytes. + (*self as uint).hash(state); + } } -} -impl<'a, S: Hasher, T: ?Sized + Hash> Hash for &'a mut T { - #[inline] - fn hash(&self, state: &mut S) { - (**self).hash(state); + impl Hash for *mut T { + #[inline] + fn hash(&self, state: &mut S) { + // NB: raw-pointer Hash does _not_ dereference + // to the target; it just gives you the pointer-bytes. + (*self as uint).hash(state); + } } -} -impl Hash for *const T { - #[inline] - fn hash(&self, state: &mut S) { - // NB: raw-pointer Hash does _not_ dereference - // to the target; it just gives you the pointer-bytes. - (*self as uint).hash(state); + impl<'a, T, B: ?Sized, S: Hasher> Hash for Cow<'a, T, B> + where B: Hash + ToOwned + { + #[inline] + fn hash(&self, state: &mut S) { + Hash::hash(&**self, state) + } } } -impl Hash for *mut T { - #[inline] - fn hash(&self, state: &mut S) { - // NB: raw-pointer Hash does _not_ dereference - // to the target; it just gives you the pointer-bytes. - (*self as uint).hash(state); +#[cfg(not(stage0))] +mod impls { + use prelude::*; + + use borrow::{Cow, ToOwned}; + use slice; + use super::*; + + macro_rules! impl_write { + ($(($ty:ident, $meth:ident),)*) => {$( + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for $ty { + fn hash(&self, state: &mut H) { + state.$meth(*self) + } + + fn hash_slice(data: &[$ty], state: &mut H) { + let newlen = data.len() * ::$ty::BYTES; + let ptr = data.as_ptr() as *const u8; + state.write(unsafe { slice::from_raw_parts(ptr, newlen) }) + } + } + )*} } -} -impl<'a, T, B: ?Sized, S: Hasher> Hash for Cow<'a, T, B> - where B: Hash + ToOwned -{ - #[inline] - fn hash(&self, state: &mut S) { - Hash::hash(&**self, state) + impl_write! { + (u8, write_u8), + (u16, write_u16), + (u32, write_u32), + (u64, write_u64), + (usize, write_usize), + (i8, write_i8), + (i16, write_i16), + (i32, write_i32), + (i64, write_i64), + (isize, write_isize), + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for bool { + fn hash(&self, state: &mut H) { + state.write_u8(*self as u8) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for char { + fn hash(&self, state: &mut H) { + state.write_u32(*self as u32) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for str { + fn hash(&self, state: &mut H) { + state.write(self.as_bytes()); + state.write_u8(0xff) + } + } + + macro_rules! impl_hash_tuple { + () => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for () { + fn hash(&self, _state: &mut H) {} + } + ); + + ( $($name:ident)+) => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($name: Hash),*> Hash for ($($name,)*) { + #[allow(non_snake_case)] + fn hash(&self, state: &mut S) { + let ($(ref $name,)*) = *self; + $($name.hash(state);)* + } + } + ); + } + + impl_hash_tuple! {} + impl_hash_tuple! { A } + impl_hash_tuple! { A B } + impl_hash_tuple! { A B C } + impl_hash_tuple! { A B C D } + impl_hash_tuple! { A B C D E } + impl_hash_tuple! { A B C D E F } + impl_hash_tuple! { A B C D E F G } + impl_hash_tuple! { A B C D E F G H } + impl_hash_tuple! { A B C D E F G H I } + impl_hash_tuple! { A B C D E F G H I J } + impl_hash_tuple! { A B C D E F G H I J K } + impl_hash_tuple! { A B C D E F G H I J K L } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for [T] { + fn hash(&self, state: &mut H) { + self.len().hash(state); + Hash::hash_slice(self, state) + } + } + + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized + Hash> Hash for &'a T { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized + Hash> Hash for &'a mut T { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for *const T { + fn hash(&self, state: &mut H) { + state.write_usize(*self as usize) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for *mut T { + fn hash(&self, state: &mut H) { + state.write_usize(*self as usize) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T, B: ?Sized> Hash for Cow<'a, T, B> + where B: Hash + ToOwned + { + fn hash(&self, state: &mut H) { + Hash::hash(&**self, state) + } } } diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index d405d0d28beb3..ce8917cc20589 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -15,7 +15,9 @@ use prelude::*; use default::Default; -use super::{Hasher, Writer}; +use super::Hasher; +#[cfg(stage0)] +use super::Writer; /// An implementation of SipHash 2-4. /// @@ -30,6 +32,7 @@ use super::{Hasher, Writer}; /// strong, this implementation has not been reviewed for such purposes. /// As such, all cryptographic uses of this implementation are strongly /// discouraged. +#[stable(feature = "rust1", since = "1.0.0")] pub struct SipHasher { k0: u64, k1: u64, @@ -88,12 +91,14 @@ macro_rules! compress { impl SipHasher { /// Creates a new `SipHasher` with the two initial keys set to 0. #[inline] + #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> SipHasher { SipHasher::new_with_keys(0, 0) } /// Creates a `SipHasher` that is keyed off the provided keys. #[inline] + #[stable(feature = "rust1", since = "1.0.0")] pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher { let mut state = SipHasher { k0: key0, @@ -114,10 +119,16 @@ impl SipHasher { #[unstable(feature = "hash")] #[deprecated(since = "1.0.0", reason = "renamed to finish")] pub fn result(&self) -> u64 { self.finish() } -} -impl Writer for SipHasher { - #[inline] + fn reset(&mut self) { + self.length = 0; + self.v0 = self.k0 ^ 0x736f6d6570736575; + self.v1 = self.k1 ^ 0x646f72616e646f6d; + self.v2 = self.k0 ^ 0x6c7967656e657261; + self.v3 = self.k1 ^ 0x7465646279746573; + self.ntail = 0; + } + fn write(&mut self, msg: &[u8]) { let length = msg.len(); self.length += length; @@ -164,16 +175,28 @@ impl Writer for SipHasher { } } +#[cfg(stage0)] +impl Writer for SipHasher { + #[inline] + fn write(&mut self, msg: &[u8]) { + self.write(msg) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] impl Hasher for SipHasher { + #[cfg(stage0)] type Output = u64; + #[cfg(stage0)] fn reset(&mut self) { - self.length = 0; - self.v0 = self.k0 ^ 0x736f6d6570736575; - self.v1 = self.k1 ^ 0x646f72616e646f6d; - self.v2 = self.k0 ^ 0x6c7967656e657261; - self.v3 = self.k1 ^ 0x7465646279746573; - self.ntail = 0; + self.reset(); + } + + #[inline] + #[cfg(not(stage0))] + fn write(&mut self, msg: &[u8]) { + self.write(msg) } fn finish(&self) -> u64 { @@ -199,6 +222,7 @@ impl Hasher for SipHasher { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Clone for SipHasher { #[inline] fn clone(&self) -> SipHasher { @@ -216,6 +240,7 @@ impl Clone for SipHasher { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Default for SipHasher { fn default() -> SipHasher { SipHasher::new() diff --git a/src/libcoretest/hash/mod.rs b/src/libcoretest/hash/mod.rs index 2da3f370b40ac..11e5e6f334f13 100644 --- a/src/libcoretest/hash/mod.rs +++ b/src/libcoretest/hash/mod.rs @@ -9,7 +9,7 @@ // except according to those terms. use std::mem; -use std::hash::{Hash, Hasher, Writer}; +use std::hash::{Hash, Hasher}; use std::default::Default; struct MyHasher { @@ -22,25 +22,20 @@ impl Default for MyHasher { } } -impl Writer for MyHasher { - // Most things we'll just add up the bytes. +impl Hasher for MyHasher { + type Output = u64; fn write(&mut self, buf: &[u8]) { for byte in buf { self.hash += *byte as u64; } } -} - -impl Hasher for MyHasher { - type Output = u64; - fn reset(&mut self) { self.hash = 0; } fn finish(&self) -> u64 { self.hash } } #[test] fn test_writer_hasher() { - fn hash>(t: &T) -> u64 { + fn hash(t: &T) -> u64 { ::std::hash::hash::<_, MyHasher>(t) } @@ -91,8 +86,9 @@ struct CustomHasher { output: u64 } impl Hasher for CustomHasher { type Output = u64; - fn reset(&mut self) { self.output = 0; } fn finish(&self) -> u64 { self.output } + fn write(&mut self, data: &[u8]) { panic!() } + fn write_u64(&mut self, data: u64) { self.output = data; } } impl Default for CustomHasher { @@ -101,15 +97,15 @@ impl Default for CustomHasher { } } -impl Hash for Custom { - fn hash(&self, state: &mut CustomHasher) { - state.output = self.hash; +impl Hash for Custom { + fn hash(&self, state: &mut H) { + state.write_u64(self.hash); } } #[test] fn test_custom_state() { - fn hash>(t: &T) -> u64 { + fn hash(t: &T) -> u64 { ::std::hash::hash::<_, CustomHasher>(t) } diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 5dc23d27ee11b..bdcc10ebceca0 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -185,12 +185,20 @@ impl PartialEq for LintId { impl Eq for LintId { } +#[cfg(stage0)] impl hash::Hash for LintId { fn hash(&self, state: &mut S) { let ptr = self.lint as *const Lint; ptr.hash(state); } } +#[cfg(not(stage0))] +impl hash::Hash for LintId { + fn hash(&self, state: &mut H) { + let ptr = self.lint as *const Lint; + ptr.hash(state); + } +} impl LintId { /// Get the `LintId` for a `Lint`. diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 3123fa31abdd1..06c6f0c118346 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1588,6 +1588,7 @@ fn encode_info_for_items(ecx: &EncodeContext, // Path and definition ID indexing +#[cfg(stage0)] fn encode_index(rbml_w: &mut Encoder, index: Vec>, mut write_fn: F) where F: FnMut(&mut SeekableMemWriter, &T), T: Hash, @@ -1628,6 +1629,47 @@ fn encode_index(rbml_w: &mut Encoder, index: Vec>, mut write_fn: rbml_w.end_tag(); rbml_w.end_tag(); } +#[cfg(not(stage0))] +fn encode_index(rbml_w: &mut Encoder, index: Vec>, mut write_fn: F) where + F: FnMut(&mut SeekableMemWriter, &T), + T: Hash, +{ + let mut buckets: Vec>> = (0..256u16).map(|_| Vec::new()).collect(); + for elt in index { + let mut s = SipHasher::new(); + elt.val.hash(&mut s); + let h = s.finish() as uint; + (&mut buckets[h % 256]).push(elt); + } + + rbml_w.start_tag(tag_index); + let mut bucket_locs = Vec::new(); + rbml_w.start_tag(tag_index_buckets); + for bucket in &buckets { + bucket_locs.push(rbml_w.writer.tell().unwrap()); + rbml_w.start_tag(tag_index_buckets_bucket); + for elt in bucket { + rbml_w.start_tag(tag_index_buckets_bucket_elt); + assert!(elt.pos < 0xffff_ffff); + { + let wr: &mut SeekableMemWriter = rbml_w.writer; + wr.write_be_u32(elt.pos as u32); + } + write_fn(rbml_w.writer, &elt.val); + rbml_w.end_tag(); + } + rbml_w.end_tag(); + } + rbml_w.end_tag(); + rbml_w.start_tag(tag_index_table); + for pos in &bucket_locs { + assert!(*pos < 0xffff_ffff); + let wr: &mut SeekableMemWriter = rbml_w.writer; + wr.write_be_u32(*pos as u32); + } + rbml_w.end_tag(); + rbml_w.end_tag(); +} fn write_i64(writer: &mut SeekableMemWriter, &n: &i64) { let wr: &mut SeekableMemWriter = writer; diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8618bde95fe6f..b3aff92ae5364 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -72,7 +72,8 @@ use std::borrow::{BorrowFrom, Cow}; use std::cell::{Cell, RefCell}; use std::cmp; use std::fmt; -use std::hash::{Hash, Writer, SipHasher, Hasher}; +use std::hash::{Hash, SipHasher, Hasher}; +#[cfg(stage0)] use std::hash::Writer; use std::mem; use std::ops; use std::rc::Rc; @@ -958,11 +959,18 @@ impl<'tcx> PartialEq for TyS<'tcx> { } impl<'tcx> Eq for TyS<'tcx> {} +#[cfg(stage0)] impl<'tcx, S: Writer + Hasher> Hash for TyS<'tcx> { fn hash(&self, s: &mut S) { (self as *const _).hash(s) } } +#[cfg(not(stage0))] +impl<'tcx> Hash for TyS<'tcx> { + fn hash(&self, s: &mut H) { + (self as *const _).hash(s) + } +} pub type Ty<'tcx> = &'tcx TyS<'tcx>; @@ -980,11 +988,18 @@ impl<'tcx> PartialEq for InternedTy<'tcx> { impl<'tcx> Eq for InternedTy<'tcx> {} +#[cfg(stage0)] impl<'tcx, S: Writer + Hasher> Hash for InternedTy<'tcx> { fn hash(&self, s: &mut S) { self.ty.sty.hash(s) } } +#[cfg(not(stage0))] +impl<'tcx> Hash for InternedTy<'tcx> { + fn hash(&self, s: &mut H) { + self.ty.sty.hash(s) + } +} impl<'tcx> BorrowFrom> for sty<'tcx> { fn borrow_from<'a>(ty: &'a InternedTy<'tcx>) -> &'a sty<'tcx> { diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index d3d0f56c3ce90..23942c045645b 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -13,7 +13,8 @@ use std::cell::{RefCell, Cell}; use std::collections::HashMap; use std::fmt::Debug; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; +#[cfg(stage0)] use std::hash::Hasher; use std::iter::repeat; use std::time::Duration; use std::collections::hash_state::HashState; @@ -144,11 +145,54 @@ pub fn block_query

(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) - /// Efficiency note: This is implemented in an inefficient way because it is typically invoked on /// very small graphs. If the graphs become larger, a more efficient graph representation and /// algorithm would probably be advised. +#[cfg(stage0)] pub fn can_reach(edges_map: &HashMap, S>, source: T, destination: T) -> bool where S: HashState, ::Hasher: Hasher, - T: Hash< ::Hasher> + Eq + Clone, + T: Hash<::Hasher> + Eq + Clone, +{ + if source == destination { + return true; + } + + // Do a little breadth-first-search here. The `queue` list + // doubles as a way to detect if we've seen a particular FR + // before. Note that we expect this graph to be an *extremely + // shallow* tree. + let mut queue = vec!(source); + let mut i = 0; + while i < queue.len() { + match edges_map.get(&queue[i]) { + Some(edges) => { + for target in edges { + if *target == destination { + return true; + } + + if !queue.iter().any(|x| x == target) { + queue.push((*target).clone()); + } + } + } + None => {} + } + i += 1; + } + return false; +} +/// K: Eq + Hash, V, S, H: Hasher +/// +/// Determines whether there exists a path from `source` to `destination`. The graph is defined by +/// the `edges_map`, which maps from a node `S` to a list of its adjacent nodes `T`. +/// +/// Efficiency note: This is implemented in an inefficient way because it is typically invoked on +/// very small graphs. If the graphs become larger, a more efficient graph representation and +/// algorithm would probably be advised. +#[cfg(not(stage0))] +pub fn can_reach(edges_map: &HashMap, S>, source: T, + destination: T) -> bool + where S: HashState, T: Hash + Eq + Clone, { if source == destination { return true; @@ -206,6 +250,7 @@ pub fn can_reach(edges_map: &HashMap, S>, source: T, /// } /// ``` #[inline(always)] +#[cfg(stage0)] pub fn memoized(cache: &RefCell>, arg: T, f: F) -> U where T: Clone + Hash<::Hasher> + Eq, U: Clone, @@ -224,3 +269,47 @@ pub fn memoized(cache: &RefCell>, arg: T, f: F) -> } } } +/// Memoizes a one-argument closure using the given RefCell containing +/// a type implementing MutableMap to serve as a cache. +/// +/// In the future the signature of this function is expected to be: +/// ``` +/// pub fn memoized>( +/// cache: &RefCell, +/// f: &|T| -> U +/// ) -> impl |T| -> U { +/// ``` +/// but currently it is not possible. +/// +/// # Example +/// ``` +/// struct Context { +/// cache: RefCell> +/// } +/// +/// fn factorial(ctxt: &Context, n: uint) -> uint { +/// memoized(&ctxt.cache, n, |n| match n { +/// 0 | 1 => n, +/// _ => factorial(ctxt, n - 2) + factorial(ctxt, n - 1) +/// }) +/// } +/// ``` +#[inline(always)] +#[cfg(not(stage0))] +pub fn memoized(cache: &RefCell>, arg: T, f: F) -> U + where T: Clone + Hash + Eq, + U: Clone, + S: HashState, + F: FnOnce(T) -> U, +{ + let key = arg.clone(); + let result = cache.borrow().get(&key).map(|result| result.clone()); + match result { + Some(result) => result, + None => { + let result = f(arg); + cache.borrow_mut().insert(key, result.clone()); + result + } + } +} diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs index f8e3defe19d63..1b07ce789e77c 100644 --- a/src/librustc/util/nodemap.rs +++ b/src/librustc/util/nodemap.rs @@ -15,7 +15,8 @@ use std::collections::hash_state::{DefaultState}; use std::collections::{HashMap, HashSet}; use std::default::Default; -use std::hash::{Hasher, Writer, Hash}; +use std::hash::{Hasher, Hash}; +#[cfg(stage0)] use std::hash::Writer; use syntax::ast; pub type FnvHashMap = HashMap>; @@ -27,12 +28,22 @@ pub type DefIdMap = FnvHashMap; pub type NodeSet = FnvHashSet; pub type DefIdSet = FnvHashSet; +#[cfg(stage0)] pub fn FnvHashMap + Eq, V>() -> FnvHashMap { Default::default() } +#[cfg(stage0)] pub fn FnvHashSet + Eq>() -> FnvHashSet { Default::default() } +#[cfg(not(stage0))] +pub fn FnvHashMap() -> FnvHashMap { + Default::default() +} +#[cfg(not(stage0))] +pub fn FnvHashSet() -> FnvHashSet { + Default::default() +} pub fn NodeMap() -> NodeMap { FnvHashMap() } pub fn DefIdMap() -> DefIdMap { FnvHashMap() } @@ -52,12 +63,14 @@ impl Default for FnvHasher { fn default() -> FnvHasher { FnvHasher(0xcbf29ce484222325) } } +#[cfg(stage0)] impl Hasher for FnvHasher { type Output = u64; fn reset(&mut self) { *self = Default::default(); } fn finish(&self) -> u64 { self.0 } } +#[cfg(stage0)] impl Writer for FnvHasher { fn write(&mut self, bytes: &[u8]) { let FnvHasher(mut hash) = *self; @@ -68,3 +81,16 @@ impl Writer for FnvHasher { *self = FnvHasher(hash); } } + +#[cfg(not(stage0))] +impl Hasher for FnvHasher { + fn write(&mut self, bytes: &[u8]) { + let FnvHasher(mut hash) = *self; + for byte in bytes { + hash = hash ^ (*byte as u64); + hash = hash * 0x100000001b3; + } + *self = FnvHasher(hash); + } + fn finish(&self) -> u64 { self.0 } +} diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 426101e858a89..47708b47e84a4 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -28,7 +28,8 @@ use middle::ty_fold::TypeFoldable; use std::collections::HashMap; use std::collections::hash_state::HashState; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; +#[cfg(stage0)] use std::hash::Hasher; use std::rc::Rc; use syntax::abi; use syntax::ast_map; @@ -1420,6 +1421,7 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for ty::Binder { } } +#[cfg(stage0)] impl<'tcx, S, K, V> Repr<'tcx> for HashMap where K: Hash<::Hasher> + Eq + Repr<'tcx>, V: Repr<'tcx>, @@ -1435,6 +1437,21 @@ impl<'tcx, S, K, V> Repr<'tcx> for HashMap } } +#[cfg(not(stage0))] +impl<'tcx, S, K, V> Repr<'tcx> for HashMap + where K: Hash + Eq + Repr<'tcx>, + V: Repr<'tcx>, + S: HashState, +{ + fn repr(&self, tcx: &ctxt<'tcx>) -> String { + format!("HashMap({})", + self.iter() + .map(|(k,v)| format!("{} => {}", k.repr(tcx), v.repr(tcx))) + .collect::>() + .connect(", ")) + } +} + impl<'tcx, T, U> Repr<'tcx> for ty::OutlivesPredicate where T : Repr<'tcx> + TypeFoldable<'tcx>, U : Repr<'tcx> + TypeFoldable<'tcx>, diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index c2677cc3fd0b3..b7cfda2809257 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -20,7 +20,6 @@ #![allow(non_camel_case_types)] #![feature(core)] -#![feature(hash)] #![feature(int_uint)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index aa90d7c851ba6..21320a987adf7 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -25,7 +25,6 @@ #![feature(box_syntax)] #![feature(collections)] #![feature(core)] -#![feature(hash)] #![feature(int_uint)] #![feature(libc)] #![feature(link_args)] diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 874c8f2a9402d..17ad1396b8ecc 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -20,7 +20,6 @@ #![feature(alloc)] #![feature(collections)] #![feature(core)] -#![feature(hash)] #![feature(int_uint)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 4606200d058c6..3deca436a1f90 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -28,7 +28,6 @@ #![feature(box_syntax)] #![feature(collections)] #![feature(core)] -#![feature(hash)] #![feature(int_uint)] #![feature(old_io)] #![feature(env)] diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index bab734db12650..f9e0948d7bc8a 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -23,7 +23,6 @@ #![feature(collections)] #![feature(core)] #![feature(env)] -#![feature(hash)] #![feature(int_uint)] #![feature(old_io)] #![feature(libc)] diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs index f81edca837198..7176ad7f88da3 100644 --- a/src/libserialize/collection_impls.rs +++ b/src/libserialize/collection_impls.rs @@ -12,7 +12,8 @@ use std::usize; use std::default::Default; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; +#[cfg(stage0)] use std::hash::Hasher; use std::collections::hash_state::HashState; use {Decodable, Encodable, Decoder, Encoder}; @@ -157,6 +158,7 @@ impl< } } +#[cfg(stage0)] impl Encodable for HashMap where K: Encodable + Hash< ::Hasher> + Eq, V: Encodable, @@ -175,7 +177,26 @@ impl Encodable for HashMap }) } } +#[cfg(not(stage0))] +impl Encodable for HashMap + where K: Encodable + Hash + Eq, + V: Encodable, + S: HashState, +{ + fn encode(&self, e: &mut E) -> Result<(), E::Error> { + e.emit_map(self.len(), |e| { + let mut i = 0; + for (key, val) in self { + try!(e.emit_map_elt_key(i, |e| key.encode(e))); + try!(e.emit_map_elt_val(i, |e| val.encode(e))); + i += 1; + } + Ok(()) + }) + } +} +#[cfg(stage0)] impl Decodable for HashMap where K: Decodable + Hash< ::Hasher> + Eq, V: Decodable, @@ -195,7 +216,27 @@ impl Decodable for HashMap }) } } +#[cfg(not(stage0))] +impl Decodable for HashMap + where K: Decodable + Hash + Eq, + V: Decodable, + S: HashState + Default, +{ + fn decode(d: &mut D) -> Result, D::Error> { + d.read_map(|d, len| { + let state = Default::default(); + let mut map = HashMap::with_capacity_and_hash_state(len, state); + for i in 0..len { + let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d))); + let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d))); + map.insert(key, val); + } + Ok(map) + }) + } +} +#[cfg(stage0)] impl Encodable for HashSet where T: Encodable + Hash< ::Hasher> + Eq, S: HashState, @@ -212,7 +253,24 @@ impl Encodable for HashSet }) } } +#[cfg(not(stage0))] +impl Encodable for HashSet + where T: Encodable + Hash + Eq, + S: HashState, +{ + fn encode(&self, s: &mut E) -> Result<(), E::Error> { + s.emit_seq(self.len(), |s| { + let mut i = 0; + for e in self { + try!(s.emit_seq_elt(i, |s| e.encode(s))); + i += 1; + } + Ok(()) + }) + } +} +#[cfg(stage0)] impl Decodable for HashSet where T: Decodable + Hash< ::Hasher> + Eq, S: HashState + Default, @@ -229,6 +287,22 @@ impl Decodable for HashSet }) } } +#[cfg(not(stage0))] +impl Decodable for HashSet + where T: Decodable + Hash + Eq, + S: HashState + Default, +{ + fn decode(d: &mut D) -> Result, D::Error> { + d.read_seq(|d, len| { + let state = Default::default(); + let mut set = HashSet::with_capacity_and_hash_state(len, state); + for i in 0..len { + set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); + } + Ok(set) + }) + } +} impl Encodable for VecMap { fn encode(&self, e: &mut S) -> Result<(), S::Error> { diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 853da598ab5be..d476fd72abc3b 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -31,7 +31,6 @@ Core encoding and decoding interfaces. #![feature(int_uint)] #![feature(old_io)] #![feature(old_path)] -#![feature(hash)] #![feature(rustc_private)] #![feature(staged_api)] #![feature(std_misc)] diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 1b9f8b9901723..f04bbbb1f4dc9 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -19,7 +19,7 @@ use clone::Clone; use cmp::{max, Eq, PartialEq}; use default::Default; use fmt::{self, Debug}; -use hash::{self, Hash, SipHasher}; +use hash::{Hash, SipHasher}; use iter::{self, Iterator, ExactSizeIterator, IntoIterator, IteratorExt, FromIterator, Extend, Map}; use marker::Sized; use mem::{self, replace}; @@ -440,12 +440,10 @@ impl SearchResult { } } -impl HashMap - where K: Eq + Hash, - S: HashState, - H: hash::Hasher +impl HashMap + where K: Eq + Hash, S: HashState { - fn make_hash(&self, x: &X) -> SafeHash where X: Hash { + fn make_hash(&self, x: &X) -> SafeHash where X: Hash { table::make_hash(&self.hash_state, x) } @@ -453,7 +451,7 @@ impl HashMap /// If you already have the hash for the key lying around, use /// search_hashed. fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> Option> - where Q: BorrowFrom + Eq + Hash + where Q: BorrowFrom + Eq + Hash { let hash = self.make_hash(q); search_hashed(&self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k))) @@ -461,7 +459,7 @@ impl HashMap } fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> Option> - where Q: BorrowFrom + Eq + Hash + where Q: BorrowFrom + Eq + Hash { let hash = self.make_hash(q); search_hashed(&mut self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k))) @@ -490,7 +488,7 @@ impl HashMap } } -impl + Eq, V> HashMap { +impl HashMap { /// Create an empty HashMap. /// /// # Example @@ -520,10 +518,8 @@ impl + Eq, V> HashMap { } } -impl HashMap - where K: Eq + Hash, - S: HashState, - H: hash::Hasher +impl HashMap + where K: Eq + Hash, S: HashState { /// Creates an empty hashmap which will use the given hasher to hash keys. /// @@ -1037,7 +1033,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self, k: &Q) -> Option<&V> - where Q: Hash + Eq + BorrowFrom + where Q: Hash + Eq + BorrowFrom { self.search(k).map(|bucket| bucket.into_refs().1) } @@ -1060,7 +1056,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains_key(&self, k: &Q) -> bool - where Q: Hash + Eq + BorrowFrom + where Q: Hash + Eq + BorrowFrom { self.search(k).is_some() } @@ -1086,7 +1082,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> - where Q: Hash + Eq + BorrowFrom + where Q: Hash + Eq + BorrowFrom { self.search_mut(k).map(|bucket| bucket.into_mut_refs().1) } @@ -1138,7 +1134,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, k: &Q) -> Option - where Q: Hash + Eq + BorrowFrom + where Q: Hash + Eq + BorrowFrom { if self.table.size() == 0 { return None @@ -1195,10 +1191,8 @@ fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable, hash: SafeHas } } -impl PartialEq for HashMap - where K: Eq + Hash, V: PartialEq, - S: HashState, - H: hash::Hasher +impl PartialEq for HashMap + where K: Eq + Hash, V: PartialEq, S: HashState { fn eq(&self, other: &HashMap) -> bool { if self.len() != other.len() { return false; } @@ -1210,17 +1204,13 @@ impl PartialEq for HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for HashMap - where K: Eq + Hash, V: Eq, - S: HashState, - H: hash::Hasher +impl Eq for HashMap + where K: Eq + Hash, V: Eq, S: HashState {} #[stable(feature = "rust1", since = "1.0.0")] -impl Debug for HashMap - where K: Eq + Hash + Debug, V: Debug, - S: HashState, - H: hash::Hasher +impl Debug for HashMap + where K: Eq + Hash + Debug, V: Debug, S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "HashMap {{")); @@ -1235,10 +1225,9 @@ impl Debug for HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for HashMap - where K: Eq + Hash, - S: HashState + Default, - H: hash::Hasher +impl Default for HashMap + where K: Eq + Hash, + S: HashState + Default, { fn default() -> HashMap { HashMap::with_hash_state(Default::default()) @@ -1246,11 +1235,10 @@ impl Default for HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl Index for HashMap - where K: Eq + Hash, - Q: Eq + Hash + BorrowFrom, - S: HashState, - H: hash::Hasher +impl Index for HashMap + where K: Eq + Hash, + Q: Eq + Hash + BorrowFrom, + S: HashState, { type Output = V; @@ -1261,11 +1249,10 @@ impl Index for HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl IndexMut for HashMap - where K: Eq + Hash, - Q: Eq + Hash + BorrowFrom, - S: HashState, - H: hash::Hasher +impl IndexMut for HashMap + where K: Eq + Hash, + Q: Eq + Hash + BorrowFrom, + S: HashState, { #[inline] fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V { @@ -1373,10 +1360,8 @@ enum VacantEntryState { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, K, V, S, H> IntoIterator for &'a HashMap - where K: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, K, V, S> IntoIterator for &'a HashMap + where K: Eq + Hash, S: HashState { type Item = (&'a K, &'a V); type IntoIter = Iter<'a, K, V>; @@ -1387,10 +1372,8 @@ impl<'a, K, V, S, H> IntoIterator for &'a HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap - where K: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, K, V, S> IntoIterator for &'a mut HashMap + where K: Eq + Hash, S: HashState { type Item = (&'a K, &'a mut V); type IntoIter = IterMut<'a, K, V>; @@ -1401,10 +1384,8 @@ impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for HashMap - where K: Eq + Hash, - S: HashState, - H: hash::Hasher +impl IntoIterator for HashMap + where K: Eq + Hash, S: HashState { type Item = (K, V); type IntoIter = IntoIter; @@ -1550,10 +1531,8 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { } #[stable(feature = "rust1", since = "1.0.0")] -impl FromIterator<(K, V)> for HashMap - where K: Eq + Hash, - S: HashState + Default, - H: hash::Hasher +impl FromIterator<(K, V)> for HashMap + where K: Eq + Hash, S: HashState + Default { fn from_iter>(iter: T) -> HashMap { let lower = iter.size_hint().0; @@ -1565,10 +1544,8 @@ impl FromIterator<(K, V)> for HashMap } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend<(K, V)> for HashMap - where K: Eq + Hash, - S: HashState, - H: hash::Hasher +impl Extend<(K, V)> for HashMap + where K: Eq + Hash, S: HashState { fn extend>(&mut self, iter: T) { for (k, v) in iter { @@ -1606,9 +1583,9 @@ impl RandomState { #[unstable(feature = "std_misc", reason = "hashing an hash maps may be altered")] impl HashState for RandomState { - type Hasher = Hasher; - fn hasher(&self) -> Hasher { - Hasher { inner: SipHasher::new_with_keys(self.k0, self.k1) } + type Hasher = SipHasher; + fn hasher(&self) -> SipHasher { + SipHasher::new_with_keys(self.k0, self.k1) } } @@ -1621,25 +1598,6 @@ impl Default for RandomState { } } -/// A hasher implementation which is generated from `RandomState` instances. -/// -/// This is the default hasher used in a `HashMap` to hash keys. Types do not -/// typically declare an ability to explicitly hash into this particular type, -/// but rather in a `H: hash::Writer` type parameter. -#[unstable(feature = "std_misc", - reason = "hashing an hash maps may be altered")] -pub struct Hasher { inner: SipHasher } - -impl hash::Writer for Hasher { - fn write(&mut self, data: &[u8]) { self.inner.write(data) } -} - -impl hash::Hasher for Hasher { - type Output = u64; - fn reset(&mut self) { self.inner.reset() } - fn finish(&self) -> u64 { self.inner.finish() } -} - #[cfg(test)] mod test_map { use prelude::v1::*; diff --git a/src/libstd/collections/hash/map_stage0.rs b/src/libstd/collections/hash/map_stage0.rs new file mode 100644 index 0000000000000..18241c7a0c3d8 --- /dev/null +++ b/src/libstd/collections/hash/map_stage0.rs @@ -0,0 +1,2329 @@ +// Copyright 2014-2015 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. +// +// ignore-lexer-test FIXME #15883 + +use self::Entry::*; +use self::SearchResult::*; +use self::VacantEntryState::*; + +use borrow::BorrowFrom; +use clone::Clone; +use cmp::{max, Eq, PartialEq}; +use default::Default; +use fmt::{self, Debug}; +use hash::{self, Hash, SipHasher}; +use iter::{self, Iterator, ExactSizeIterator, IntoIterator, IteratorExt, FromIterator, Extend, Map}; +use marker::Sized; +use mem::{self, replace}; +use num::{Int, UnsignedInt}; +use ops::{Deref, FnMut, Index, IndexMut}; +use option::Option::{self, Some, None}; +use rand::{self, Rng}; +use result::Result::{self, Ok, Err}; + +use super::table::{ + self, + Bucket, + EmptyBucket, + FullBucket, + FullBucketImm, + FullBucketMut, + RawTable, + SafeHash +}; +use super::table::BucketState::{ + Empty, + Full, +}; +use super::state::HashState; + +const INITIAL_LOG2_CAP: usize = 5; +#[unstable(feature = "std_misc")] +pub const INITIAL_CAPACITY: usize = 1 << INITIAL_LOG2_CAP; // 2^5 + +/// The default behavior of HashMap implements a load factor of 90.9%. +/// This behavior is characterized by the following condition: +/// +/// - if size > 0.909 * capacity: grow the map +#[derive(Clone)] +struct DefaultResizePolicy; + +impl DefaultResizePolicy { + fn new() -> DefaultResizePolicy { + DefaultResizePolicy + } + + #[inline] + fn min_capacity(&self, usable_size: usize) -> usize { + // Here, we are rephrasing the logic by specifying the lower limit + // on capacity: + // + // - if `cap < size * 1.1`: grow the map + usable_size * 11 / 10 + } + + /// An inverse of `min_capacity`, approximately. + #[inline] + fn usable_capacity(&self, cap: usize) -> usize { + // As the number of entries approaches usable capacity, + // min_capacity(size) must be smaller than the internal capacity, + // so that the map is not resized: + // `min_capacity(usable_capacity(x)) <= x`. + // The left-hand side can only be smaller due to flooring by integer + // division. + // + // This doesn't have to be checked for overflow since allocation size + // in bytes will overflow earlier than multiplication by 10. + cap * 10 / 11 + } +} + +#[test] +fn test_resize_policy() { + use prelude::v1::*; + let rp = DefaultResizePolicy; + for n in 0..1000 { + assert!(rp.min_capacity(rp.usable_capacity(n)) <= n); + assert!(rp.usable_capacity(rp.min_capacity(n)) <= n); + } +} + +// The main performance trick in this hashmap is called Robin Hood Hashing. +// It gains its excellent performance from one essential operation: +// +// If an insertion collides with an existing element, and that element's +// "probe distance" (how far away the element is from its ideal location) +// is higher than how far we've already probed, swap the elements. +// +// This massively lowers variance in probe distance, and allows us to get very +// high load factors with good performance. The 90% load factor I use is rather +// conservative. +// +// > Why a load factor of approximately 90%? +// +// In general, all the distances to initial buckets will converge on the mean. +// At a load factor of α, the odds of finding the target bucket after k +// probes is approximately 1-α^k. If we set this equal to 50% (since we converge +// on the mean) and set k=8 (64-byte cache line / 8-byte hash), α=0.92. I round +// this down to make the math easier on the CPU and avoid its FPU. +// Since on average we start the probing in the middle of a cache line, this +// strategy pulls in two cache lines of hashes on every lookup. I think that's +// pretty good, but if you want to trade off some space, it could go down to one +// cache line on average with an α of 0.84. +// +// > Wait, what? Where did you get 1-α^k from? +// +// On the first probe, your odds of a collision with an existing element is α. +// The odds of doing this twice in a row is approximately α^2. For three times, +// α^3, etc. Therefore, the odds of colliding k times is α^k. The odds of NOT +// colliding after k tries is 1-α^k. +// +// The paper from 1986 cited below mentions an implementation which keeps track +// of the distance-to-initial-bucket histogram. This approach is not suitable +// for modern architectures because it requires maintaining an internal data +// structure. This allows very good first guesses, but we are most concerned +// with guessing entire cache lines, not individual indexes. Furthermore, array +// accesses are no longer linear and in one direction, as we have now. There +// is also memory and cache pressure that this would entail that would be very +// difficult to properly see in a microbenchmark. +// +// ## Future Improvements (FIXME!) +// +// Allow the load factor to be changed dynamically and/or at initialization. +// +// Also, would it be possible for us to reuse storage when growing the +// underlying table? This is exactly the use case for 'realloc', and may +// be worth exploring. +// +// ## Future Optimizations (FIXME!) +// +// Another possible design choice that I made without any real reason is +// parameterizing the raw table over keys and values. Technically, all we need +// is the size and alignment of keys and values, and the code should be just as +// efficient (well, we might need one for power-of-two size and one for not...). +// This has the potential to reduce code bloat in rust executables, without +// really losing anything except 4 words (key size, key alignment, val size, +// val alignment) which can be passed in to every call of a `RawTable` function. +// This would definitely be an avenue worth exploring if people start complaining +// about the size of rust executables. +// +// Annotate exceedingly likely branches in `table::make_hash` +// and `search_hashed` to reduce instruction cache pressure +// and mispredictions once it becomes possible (blocked on issue #11092). +// +// Shrinking the table could simply reallocate in place after moving buckets +// to the first half. +// +// The growth algorithm (fragment of the Proof of Correctness) +// -------------------- +// +// The growth algorithm is basically a fast path of the naive reinsertion- +// during-resize algorithm. Other paths should never be taken. +// +// Consider growing a robin hood hashtable of capacity n. Normally, we do this +// by allocating a new table of capacity `2n`, and then individually reinsert +// each element in the old table into the new one. This guarantees that the +// new table is a valid robin hood hashtable with all the desired statistical +// properties. Remark that the order we reinsert the elements in should not +// matter. For simplicity and efficiency, we will consider only linear +// reinsertions, which consist of reinserting all elements in the old table +// into the new one by increasing order of index. However we will not be +// starting our reinsertions from index 0 in general. If we start from index +// i, for the purpose of reinsertion we will consider all elements with real +// index j < i to have virtual index n + j. +// +// Our hash generation scheme consists of generating a 64-bit hash and +// truncating the most significant bits. When moving to the new table, we +// simply introduce a new bit to the front of the hash. Therefore, if an +// elements has ideal index i in the old table, it can have one of two ideal +// locations in the new table. If the new bit is 0, then the new ideal index +// is i. If the new bit is 1, then the new ideal index is n + i. Intuitively, +// we are producing two independent tables of size n, and for each element we +// independently choose which table to insert it into with equal probability. +// However the rather than wrapping around themselves on overflowing their +// indexes, the first table overflows into the first, and the first into the +// second. Visually, our new table will look something like: +// +// [yy_xxx_xxxx_xxx|xx_yyy_yyyy_yyy] +// +// Where x's are elements inserted into the first table, y's are elements +// inserted into the second, and _'s are empty sections. We now define a few +// key concepts that we will use later. Note that this is a very abstract +// perspective of the table. A real resized table would be at least half +// empty. +// +// Theorem: A linear robin hood reinsertion from the first ideal element +// produces identical results to a linear naive reinsertion from the same +// element. +// +// FIXME(Gankro, pczarn): review the proof and put it all in a separate doc.rs + +/// A hash map implementation which uses linear probing with Robin +/// Hood bucket stealing. +/// +/// The hashes are all keyed by the task-local random number generator +/// on creation by default. This means that the ordering of the keys is +/// randomized, but makes the tables more resistant to +/// denial-of-service attacks (Hash DoS). This behaviour can be +/// overridden with one of the constructors. +/// +/// It is required that the keys implement the `Eq` and `Hash` traits, although +/// this can frequently be achieved by using `#[derive(Eq, Hash)]`. +/// +/// Relevant papers/articles: +/// +/// 1. Pedro Celis. ["Robin Hood Hashing"](https://cs.uwaterloo.ca/research/tr/1986/CS-86-14.pdf) +/// 2. Emmanuel Goossaert. ["Robin Hood +/// hashing"](http://codecapsule.com/2013/11/11/robin-hood-hashing/) +/// 3. Emmanuel Goossaert. ["Robin Hood hashing: backward shift +/// deletion"](http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/) +/// +/// # Example +/// +/// ``` +/// use std::collections::HashMap; +/// +/// // type inference lets us omit an explicit type signature (which +/// // would be `HashMap<&str, &str>` in this example). +/// let mut book_reviews = HashMap::new(); +/// +/// // review some books. +/// book_reviews.insert("Adventures of Huckleberry Finn", "My favorite book."); +/// book_reviews.insert("Grimms' Fairy Tales", "Masterpiece."); +/// book_reviews.insert("Pride and Prejudice", "Very enjoyable."); +/// book_reviews.insert("The Adventures of Sherlock Holmes", "Eye lyked it alot."); +/// +/// // check for a specific one. +/// if !book_reviews.contains_key(&("Les Misérables")) { +/// println!("We've got {} reviews, but Les Misérables ain't one.", +/// book_reviews.len()); +/// } +/// +/// // oops, this review has a lot of spelling mistakes, let's delete it. +/// book_reviews.remove(&("The Adventures of Sherlock Holmes")); +/// +/// // look up the values associated with some keys. +/// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"]; +/// for book in to_find.iter() { +/// match book_reviews.get(book) { +/// Some(review) => println!("{}: {}", *book, *review), +/// None => println!("{} is unreviewed.", *book) +/// } +/// } +/// +/// // iterate over everything. +/// for (book, review) in book_reviews.iter() { +/// println!("{}: \"{}\"", *book, *review); +/// } +/// ``` +/// +/// The easiest way to use `HashMap` with a custom type as key is to derive `Eq` and `Hash`. +/// We must also derive `PartialEq`. +/// +/// ``` +/// use std::collections::HashMap; +/// +/// #[derive(Hash, Eq, PartialEq, Debug)] +/// struct Viking { +/// name: String, +/// country: String, +/// } +/// +/// impl Viking { +/// /// Create a new Viking. +/// fn new(name: &str, country: &str) -> Viking { +/// Viking { name: name.to_string(), country: country.to_string() } +/// } +/// } +/// +/// // Use a HashMap to store the vikings' health points. +/// let mut vikings = HashMap::new(); +/// +/// vikings.insert(Viking::new("Einar", "Norway"), 25); +/// vikings.insert(Viking::new("Olaf", "Denmark"), 24); +/// vikings.insert(Viking::new("Harald", "Iceland"), 12); +/// +/// // Use derived implementation to print the status of the vikings. +/// for (viking, health) in vikings.iter() { +/// println!("{:?} has {} hp", viking, health); +/// } +/// ``` +#[derive(Clone)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct HashMap { + // All hashes are keyed on these values, to prevent hash collision attacks. + hash_state: S, + + table: RawTable, + + resize_policy: DefaultResizePolicy, +} + +/// Search for a pre-hashed key. +fn search_hashed(table: M, + hash: SafeHash, + mut is_match: F) + -> SearchResult where + M: Deref>, + F: FnMut(&K) -> bool, +{ + let size = table.size(); + let mut probe = Bucket::new(table, hash); + let ib = probe.index(); + + while probe.index() != ib + size { + let full = match probe.peek() { + Empty(b) => return TableRef(b.into_table()), // hit an empty bucket + Full(b) => b + }; + + if full.distance() + ib < full.index() { + // We can finish the search early if we hit any bucket + // with a lower distance to initial bucket than we've probed. + return TableRef(full.into_table()); + } + + // If the hash doesn't match, it can't be this one.. + if hash == full.hash() { + // If the key doesn't match, it can't be this one.. + if is_match(full.read().0) { + return FoundExisting(full); + } + } + + probe = full.next(); + } + + TableRef(probe.into_table()) +} + +fn pop_internal(starting_bucket: FullBucketMut) -> (K, V) { + let (empty, retkey, retval) = starting_bucket.take(); + let mut gap = match empty.gap_peek() { + Some(b) => b, + None => return (retkey, retval) + }; + + while gap.full().distance() != 0 { + gap = match gap.shift() { + Some(b) => b, + None => break + }; + } + + // Now we've done all our shifting. Return the value we grabbed earlier. + (retkey, retval) +} + +/// Perform robin hood bucket stealing at the given `bucket`. You must +/// also pass the position of that bucket's initial bucket so we don't have +/// to recalculate it. +/// +/// `hash`, `k`, and `v` are the elements to "robin hood" into the hashtable. +fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>, + mut ib: usize, + mut hash: SafeHash, + mut k: K, + mut v: V) + -> &'a mut V { + let starting_index = bucket.index(); + let size = { + let table = bucket.table(); // FIXME "lifetime too short". + table.size() + }; + // There can be at most `size - dib` buckets to displace, because + // in the worst case, there are `size` elements and we already are + // `distance` buckets away from the initial one. + let idx_end = starting_index + size - bucket.distance(); + + loop { + let (old_hash, old_key, old_val) = bucket.replace(hash, k, v); + loop { + let probe = bucket.next(); + assert!(probe.index() != idx_end); + + let full_bucket = match probe.peek() { + Empty(bucket) => { + // Found a hole! + let b = bucket.put(old_hash, old_key, old_val); + // Now that it's stolen, just read the value's pointer + // right out of the table! + return Bucket::at_index(b.into_table(), starting_index) + .peek() + .expect_full() + .into_mut_refs() + .1; + }, + Full(bucket) => bucket + }; + + let probe_ib = full_bucket.index() - full_bucket.distance(); + + bucket = full_bucket; + + // Robin hood! Steal the spot. + if ib < probe_ib { + ib = probe_ib; + hash = old_hash; + k = old_key; + v = old_val; + break; + } + } + } +} + +/// A result that works like Option> but preserves +/// the reference that grants us access to the table in any case. +enum SearchResult { + // This is an entry that holds the given key: + FoundExisting(FullBucket), + + // There was no such entry. The reference is given back: + TableRef(M) +} + +impl SearchResult { + fn into_option(self) -> Option> { + match self { + FoundExisting(bucket) => Some(bucket), + TableRef(_) => None + } + } +} + +impl HashMap + where K: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + fn make_hash(&self, x: &X) -> SafeHash where X: Hash { + table::make_hash(&self.hash_state, x) + } + + /// Search for a key, yielding the index if it's found in the hashtable. + /// If you already have the hash for the key lying around, use + /// search_hashed. + fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> Option> + where Q: BorrowFrom + Eq + Hash + { + let hash = self.make_hash(q); + search_hashed(&self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k))) + .into_option() + } + + fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> Option> + where Q: BorrowFrom + Eq + Hash + { + let hash = self.make_hash(q); + search_hashed(&mut self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k))) + .into_option() + } + + // The caller should ensure that invariants by Robin Hood Hashing hold. + fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) { + let cap = self.table.capacity(); + let mut buckets = Bucket::new(&mut self.table, hash); + let ib = buckets.index(); + + while buckets.index() != ib + cap { + // We don't need to compare hashes for value swap. + // Not even DIBs for Robin Hood. + buckets = match buckets.peek() { + Empty(empty) => { + empty.put(hash, k, v); + return; + } + Full(b) => b.into_bucket() + }; + buckets.next(); + } + panic!("Internal HashMap error: Out of space."); + } +} + +impl + Eq, V> HashMap { + /// Create an empty HashMap. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// let mut map: HashMap<&str, int> = HashMap::new(); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn new() -> HashMap { + Default::default() + } + + /// Creates an empty hash map with the given initial capacity. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn with_capacity(capacity: usize) -> HashMap { + HashMap::with_capacity_and_hash_state(capacity, Default::default()) + } +} + +impl HashMap + where K: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + /// Creates an empty hashmap which will use the given hasher to hash keys. + /// + /// The creates map has the default initial capacity. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::RandomState; + /// + /// let s = RandomState::new(); + /// let mut map = HashMap::with_hash_state(s); + /// map.insert(1, 2); + /// ``` + #[inline] + #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")] + pub fn with_hash_state(hash_state: S) -> HashMap { + HashMap { + hash_state: hash_state, + resize_policy: DefaultResizePolicy::new(), + table: RawTable::new(0), + } + } + + /// Create an empty HashMap with space for at least `capacity` + /// elements, using `hasher` to hash the keys. + /// + /// Warning: `hasher` is normally randomly generated, and + /// is designed to allow HashMaps to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::RandomState; + /// + /// let s = RandomState::new(); + /// let mut map = HashMap::with_capacity_and_hash_state(10, s); + /// map.insert(1, 2); + /// ``` + #[inline] + #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")] + pub fn with_capacity_and_hash_state(capacity: usize, hash_state: S) + -> HashMap { + let resize_policy = DefaultResizePolicy::new(); + let min_cap = max(INITIAL_CAPACITY, resize_policy.min_capacity(capacity)); + let internal_cap = min_cap.checked_next_power_of_two().expect("capacity overflow"); + assert!(internal_cap >= capacity, "capacity overflow"); + HashMap { + hash_state: hash_state, + resize_policy: resize_policy, + table: RawTable::new(internal_cap), + } + } + + /// Returns the number of elements the map can hold without reallocating. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// let map: HashMap = HashMap::with_capacity(100); + /// assert!(map.capacity() >= 100); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn capacity(&self) -> usize { + self.resize_policy.usable_capacity(self.table.capacity()) + } + + /// Reserves capacity for at least `additional` more elements to be inserted + /// in the `HashMap`. The collection may reserve more space to avoid + /// frequent reallocations. + /// + /// # Panics + /// + /// Panics if the new allocation size overflows `usize`. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// let mut map: HashMap<&str, int> = HashMap::new(); + /// map.reserve(10); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn reserve(&mut self, additional: usize) { + let new_size = self.len().checked_add(additional).expect("capacity overflow"); + let min_cap = self.resize_policy.min_capacity(new_size); + + // An invalid value shouldn't make us run out of space. This includes + // an overflow check. + assert!(new_size <= min_cap); + + if self.table.capacity() < min_cap { + let new_capacity = max(min_cap.next_power_of_two(), INITIAL_CAPACITY); + self.resize(new_capacity); + } + } + + /// Resizes the internal vectors to a new capacity. It's your responsibility to: + /// 1) Make sure the new capacity is enough for all the elements, accounting + /// for the load factor. + /// 2) Ensure new_capacity is a power of two or zero. + fn resize(&mut self, new_capacity: usize) { + assert!(self.table.size() <= new_capacity); + assert!(new_capacity.is_power_of_two() || new_capacity == 0); + + let mut old_table = replace(&mut self.table, RawTable::new(new_capacity)); + let old_size = old_table.size(); + + if old_table.capacity() == 0 || old_table.size() == 0 { + return; + } + + // Grow the table. + // Specialization of the other branch. + let mut bucket = Bucket::first(&mut old_table); + + // "So a few of the first shall be last: for many be called, + // but few chosen." + // + // We'll most likely encounter a few buckets at the beginning that + // have their initial buckets near the end of the table. They were + // placed at the beginning as the probe wrapped around the table + // during insertion. We must skip forward to a bucket that won't + // get reinserted too early and won't unfairly steal others spot. + // This eliminates the need for robin hood. + loop { + bucket = match bucket.peek() { + Full(full) => { + if full.distance() == 0 { + // This bucket occupies its ideal spot. + // It indicates the start of another "cluster". + bucket = full.into_bucket(); + break; + } + // Leaving this bucket in the last cluster for later. + full.into_bucket() + } + Empty(b) => { + // Encountered a hole between clusters. + b.into_bucket() + } + }; + bucket.next(); + } + + // This is how the buckets might be laid out in memory: + // ($ marks an initialized bucket) + // ________________ + // |$$$_$$$$$$_$$$$$| + // + // But we've skipped the entire initial cluster of buckets + // and will continue iteration in this order: + // ________________ + // |$$$$$$_$$$$$ + // ^ wrap around once end is reached + // ________________ + // $$$_____________| + // ^ exit once table.size == 0 + loop { + bucket = match bucket.peek() { + Full(bucket) => { + let h = bucket.hash(); + let (b, k, v) = bucket.take(); + self.insert_hashed_ordered(h, k, v); + { + let t = b.table(); // FIXME "lifetime too short". + if t.size() == 0 { break } + }; + b.into_bucket() + } + Empty(b) => b.into_bucket() + }; + bucket.next(); + } + + assert_eq!(self.table.size(), old_size); + } + + /// Shrinks the capacity of the map as much as possible. It will drop + /// down as much as possible while maintaining the internal rules + /// and possibly leaving some space in accordance with the resize policy. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map: HashMap = HashMap::with_capacity(100); + /// map.insert(1, 2); + /// map.insert(3, 4); + /// assert!(map.capacity() >= 100); + /// map.shrink_to_fit(); + /// assert!(map.capacity() >= 2); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn shrink_to_fit(&mut self) { + let min_capacity = self.resize_policy.min_capacity(self.len()); + let min_capacity = max(min_capacity.next_power_of_two(), INITIAL_CAPACITY); + + // An invalid value shouldn't make us run out of space. + debug_assert!(self.len() <= min_capacity); + + if self.table.capacity() != min_capacity { + let old_table = replace(&mut self.table, RawTable::new(min_capacity)); + let old_size = old_table.size(); + + // Shrink the table. Naive algorithm for resizing: + for (h, k, v) in old_table.into_iter() { + self.insert_hashed_nocheck(h, k, v); + } + + debug_assert_eq!(self.table.size(), old_size); + } + } + + /// Insert a pre-hashed key-value pair, without first checking + /// that there's enough room in the buckets. Returns a reference to the + /// newly insert value. + /// + /// If the key already exists, the hashtable will be returned untouched + /// and a reference to the existing element will be returned. + fn insert_hashed_nocheck(&mut self, hash: SafeHash, k: K, v: V) -> &mut V { + self.insert_or_replace_with(hash, k, v, |_, _, _| ()) + } + + fn insert_or_replace_with<'a, F>(&'a mut self, + hash: SafeHash, + k: K, + v: V, + mut found_existing: F) + -> &'a mut V where + F: FnMut(&mut K, &mut V, V), + { + // Worst case, we'll find one empty bucket among `size + 1` buckets. + let size = self.table.size(); + let mut probe = Bucket::new(&mut self.table, hash); + let ib = probe.index(); + + loop { + let mut bucket = match probe.peek() { + Empty(bucket) => { + // Found a hole! + return bucket.put(hash, k, v).into_mut_refs().1; + } + Full(bucket) => bucket + }; + + // hash matches? + if bucket.hash() == hash { + // key matches? + if k == *bucket.read_mut().0 { + let (bucket_k, bucket_v) = bucket.into_mut_refs(); + debug_assert!(k == *bucket_k); + // Key already exists. Get its reference. + found_existing(bucket_k, bucket_v, v); + return bucket_v; + } + } + + let robin_ib = bucket.index() as int - bucket.distance() as int; + + if (ib as int) < robin_ib { + // Found a luckier bucket than me. Better steal his spot. + return robin_hood(bucket, robin_ib as usize, hash, k, v); + } + + probe = bucket.next(); + assert!(probe.index() != ib + size + 1); + } + } + + /// An iterator visiting all keys in arbitrary order. + /// Iterator element type is `&'a K`. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert("a", 1); + /// map.insert("b", 2); + /// map.insert("c", 3); + /// + /// for key in map.keys() { + /// println!("{}", key); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { + fn first((a, _): (A, B)) -> A { a } + let first: fn((&'a K,&'a V)) -> &'a K = first; // coerce to fn ptr + + Keys { inner: self.iter().map(first) } + } + + /// An iterator visiting all values in arbitrary order. + /// Iterator element type is `&'a V`. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert("a", 1); + /// map.insert("b", 2); + /// map.insert("c", 3); + /// + /// for val in map.values() { + /// println!("{}", val); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn values<'a>(&'a self) -> Values<'a, K, V> { + fn second((_, b): (A, B)) -> B { b } + let second: fn((&'a K,&'a V)) -> &'a V = second; // coerce to fn ptr + + Values { inner: self.iter().map(second) } + } + + /// An iterator visiting all key-value pairs in arbitrary order. + /// Iterator element type is `(&'a K, &'a V)`. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert("a", 1); + /// map.insert("b", 2); + /// map.insert("c", 3); + /// + /// for (key, val) in map.iter() { + /// println!("key: {} val: {}", key, val); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn iter(&self) -> Iter { + Iter { inner: self.table.iter() } + } + + /// An iterator visiting all key-value pairs in arbitrary order, + /// with mutable references to the values. + /// Iterator element type is `(&'a K, &'a mut V)`. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert("a", 1); + /// map.insert("b", 2); + /// map.insert("c", 3); + /// + /// // Update all values + /// for (_, val) in map.iter_mut() { + /// *val *= 2; + /// } + /// + /// for (key, val) in map.iter() { + /// println!("key: {} val: {}", key, val); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn iter_mut(&mut self) -> IterMut { + IterMut { inner: self.table.iter_mut() } + } + + /// Creates a consuming iterator, that is, one that moves each key-value + /// pair out of the map in arbitrary order. The map cannot be used after + /// calling this. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert("a", 1); + /// map.insert("b", 2); + /// map.insert("c", 3); + /// + /// // Not possible with .iter() + /// let vec: Vec<(&str, int)> = map.into_iter().collect(); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn into_iter(self) -> IntoIter { + fn last_two((_, b, c): (A, B, C)) -> (B, C) { (b, c) } + let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two; + + IntoIter { + inner: self.table.into_iter().map(last_two) + } + } + + /// Gets the given key's corresponding entry in the map for in-place manipulation. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn entry(&mut self, key: K) -> Entry { + // Gotta resize now. + self.reserve(1); + + let hash = self.make_hash(&key); + search_entry_hashed(&mut self.table, hash, key) + } + + /// Returns the number of elements in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut a = HashMap::new(); + /// assert_eq!(a.len(), 0); + /// a.insert(1, "a"); + /// assert_eq!(a.len(), 1); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn len(&self) -> usize { self.table.size() } + + /// Returns true if the map contains no elements. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut a = HashMap::new(); + /// assert!(a.is_empty()); + /// a.insert(1, "a"); + /// assert!(!a.is_empty()); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_empty(&self) -> bool { self.len() == 0 } + + /// Clears the map, returning all key-value pairs as an iterator. Keeps the + /// allocated memory for reuse. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut a = HashMap::new(); + /// a.insert(1, "a"); + /// a.insert(2, "b"); + /// + /// for (k, v) in a.drain().take(1) { + /// assert!(k == 1 || k == 2); + /// assert!(v == "a" || v == "b"); + /// } + /// + /// assert!(a.is_empty()); + /// ``` + #[inline] + #[unstable(feature = "std_misc", + reason = "matches collection reform specification, waiting for dust to settle")] + pub fn drain(&mut self) -> Drain { + fn last_two((_, b, c): (A, B, C)) -> (B, C) { (b, c) } + let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two; // coerce to fn pointer + + Drain { + inner: self.table.drain().map(last_two), + } + } + + /// Clears the map, removing all key-value pairs. Keeps the allocated memory + /// for reuse. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut a = HashMap::new(); + /// a.insert(1, "a"); + /// a.clear(); + /// assert!(a.is_empty()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn clear(&mut self) { + self.drain(); + } + + /// Returns a reference to the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the key type. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.get(&1), Some(&"a")); + /// assert_eq!(map.get(&2), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get(&self, k: &Q) -> Option<&V> + where Q: Hash + Eq + BorrowFrom + { + self.search(k).map(|bucket| bucket.into_refs().1) + } + + /// Returns true if the map contains a value for the specified key. + /// + /// The key may be any borrowed form of the map's key type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the key type. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.contains_key(&1), true); + /// assert_eq!(map.contains_key(&2), false); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn contains_key(&self, k: &Q) -> bool + where Q: Hash + Eq + BorrowFrom + { + self.search(k).is_some() + } + + /// Returns a mutable reference to the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the key type. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert(1, "a"); + /// match map.get_mut(&1) { + /// Some(x) => *x = "b", + /// None => (), + /// } + /// assert_eq!(map[1], "b"); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> + where Q: Hash + Eq + BorrowFrom + { + self.search_mut(k).map(|bucket| bucket.into_mut_refs().1) + } + + /// Inserts a key-value pair from the map. If the key already had a value + /// present in the map, that value is returned. Otherwise, `None` is returned. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// assert_eq!(map.insert(37, "a"), None); + /// assert_eq!(map.is_empty(), false); + /// + /// map.insert(37, "b"); + /// assert_eq!(map.insert(37, "c"), Some("b")); + /// assert_eq!(map[37], "c"); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn insert(&mut self, k: K, v: V) -> Option { + let hash = self.make_hash(&k); + self.reserve(1); + + let mut retval = None; + self.insert_or_replace_with(hash, k, v, |_, val_ref, val| { + retval = Some(replace(val_ref, val)); + }); + retval + } + + /// Removes a key from the map, returning the value at the key if the key + /// was previously in the map. + /// + /// The key may be any borrowed form of the map's key type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the key type. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.remove(&1), Some("a")); + /// assert_eq!(map.remove(&1), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn remove(&mut self, k: &Q) -> Option + where Q: Hash + Eq + BorrowFrom + { + if self.table.size() == 0 { + return None + } + + self.search_mut(k).map(|bucket| pop_internal(bucket).1) + } +} + +fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable, hash: SafeHash, k: K) + -> Entry<'a, K, V> +{ + // Worst case, we'll find one empty bucket among `size + 1` buckets. + let size = table.size(); + let mut probe = Bucket::new(table, hash); + let ib = probe.index(); + + loop { + let bucket = match probe.peek() { + Empty(bucket) => { + // Found a hole! + return Vacant(VacantEntry { + hash: hash, + key: k, + elem: NoElem(bucket), + }); + }, + Full(bucket) => bucket + }; + + // hash matches? + if bucket.hash() == hash { + // key matches? + if k == *bucket.read().0 { + return Occupied(OccupiedEntry{ + elem: bucket, + }); + } + } + + let robin_ib = bucket.index() as int - bucket.distance() as int; + + if (ib as int) < robin_ib { + // Found a luckier bucket than me. Better steal his spot. + return Vacant(VacantEntry { + hash: hash, + key: k, + elem: NeqElem(bucket, robin_ib as usize), + }); + } + + probe = bucket.next(); + assert!(probe.index() != ib + size + 1); + } +} + +impl PartialEq for HashMap + where K: Eq + Hash, V: PartialEq, + S: HashState, + H: hash::Hasher +{ + fn eq(&self, other: &HashMap) -> bool { + if self.len() != other.len() { return false; } + + self.iter().all(|(key, value)| + other.get(key).map_or(false, |v| *value == *v) + ) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Eq for HashMap + where K: Eq + Hash, V: Eq, + S: HashState, + H: hash::Hasher +{} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Debug for HashMap + where K: Eq + Hash + Debug, V: Debug, + S: HashState, + H: hash::Hasher +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(write!(f, "HashMap {{")); + + for (i, (k, v)) in self.iter().enumerate() { + if i != 0 { try!(write!(f, ", ")); } + try!(write!(f, "{:?}: {:?}", *k, *v)); + } + + write!(f, "}}") + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Default for HashMap + where K: Eq + Hash, + S: HashState + Default, + H: hash::Hasher +{ + fn default() -> HashMap { + HashMap::with_hash_state(Default::default()) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Index for HashMap + where K: Eq + Hash, + Q: Eq + Hash + BorrowFrom, + S: HashState, + H: hash::Hasher +{ + type Output = V; + + #[inline] + fn index<'a>(&'a self, index: &Q) -> &'a V { + self.get(index).expect("no entry found for key") + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl IndexMut for HashMap + where K: Eq + Hash, + Q: Eq + Hash + BorrowFrom, + S: HashState, + H: hash::Hasher +{ + #[inline] + fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V { + self.get_mut(index).expect("no entry found for key") + } +} + +/// HashMap iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Iter<'a, K: 'a, V: 'a> { + inner: table::Iter<'a, K, V> +} + +// FIXME(#19839) Remove in favor of `#[derive(Clone)]` +impl<'a, K, V> Clone for Iter<'a, K, V> { + fn clone(&self) -> Iter<'a, K, V> { + Iter { + inner: self.inner.clone() + } + } +} + +/// HashMap mutable values iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct IterMut<'a, K: 'a, V: 'a> { + inner: table::IterMut<'a, K, V> +} + +/// HashMap move iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct IntoIter { + inner: iter::Map, fn((SafeHash, K, V)) -> (K, V)> +} + +/// HashMap keys iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Keys<'a, K: 'a, V: 'a> { + inner: Map, fn((&'a K, &'a V)) -> &'a K> +} + +// FIXME(#19839) Remove in favor of `#[derive(Clone)]` +impl<'a, K, V> Clone for Keys<'a, K, V> { + fn clone(&self) -> Keys<'a, K, V> { + Keys { + inner: self.inner.clone() + } + } +} + +/// HashMap values iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Values<'a, K: 'a, V: 'a> { + inner: Map, fn((&'a K, &'a V)) -> &'a V> +} + +// FIXME(#19839) Remove in favor of `#[derive(Clone)]` +impl<'a, K, V> Clone for Values<'a, K, V> { + fn clone(&self) -> Values<'a, K, V> { + Values { + inner: self.inner.clone() + } + } +} + +/// HashMap drain iterator. +#[unstable(feature = "std_misc", + reason = "matches collection reform specification, waiting for dust to settle")] +pub struct Drain<'a, K: 'a, V: 'a> { + inner: iter::Map, fn((SafeHash, K, V)) -> (K, V)> +} + +/// A view into a single occupied location in a HashMap. +#[unstable(feature = "std_misc", + reason = "precise API still being fleshed out")] +pub struct OccupiedEntry<'a, K: 'a, V: 'a> { + elem: FullBucket>, +} + +/// A view into a single empty location in a HashMap. +#[unstable(feature = "std_misc", + reason = "precise API still being fleshed out")] +pub struct VacantEntry<'a, K: 'a, V: 'a> { + hash: SafeHash, + key: K, + elem: VacantEntryState>, +} + +/// A view into a single location in a map, which may be vacant or occupied. +#[unstable(feature = "std_misc", + reason = "precise API still being fleshed out")] +pub enum Entry<'a, K: 'a, V: 'a> { + /// An occupied Entry. + Occupied(OccupiedEntry<'a, K, V>), + /// A vacant Entry. + Vacant(VacantEntry<'a, K, V>), +} + +/// Possible states of a VacantEntry. +enum VacantEntryState { + /// The index is occupied, but the key to insert has precedence, + /// and will kick the current one out on insertion. + NeqElem(FullBucket, usize), + /// The index is genuinely vacant. + NoElem(EmptyBucket), +} + +impl<'a, K, V, S, H> IntoIterator for &'a HashMap + where K: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = (&'a K, &'a V); + type IntoIter = Iter<'a, K, V>; + + fn into_iter(self) -> Iter<'a, K, V> { + self.iter() + } +} + +impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap + where K: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = (&'a K, &'a mut V); + type IntoIter = IterMut<'a, K, V>; + + fn into_iter(mut self) -> IterMut<'a, K, V> { + self.iter_mut() + } +} + +impl IntoIterator for HashMap + where K: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = (K, V); + type IntoIter = IntoIter; + + fn into_iter(self) -> IntoIter { + self.into_iter() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> Iterator for Iter<'a, K, V> { + type Item = (&'a K, &'a V); + + #[inline] fn next(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> Iterator for IterMut<'a, K, V> { + type Item = (&'a K, &'a mut V); + + #[inline] fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for IntoIter { + type Item = (K, V); + + #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for IntoIter { + #[inline] fn len(&self) -> usize { self.inner.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> Iterator for Keys<'a, K, V> { + type Item = &'a K; + + #[inline] fn next(&mut self) -> Option<(&'a K)> { self.inner.next() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> Iterator for Values<'a, K, V> { + type Item = &'a V; + + #[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> Iterator for Drain<'a, K, V> { + type Item = (K, V); + + #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } +} + +#[unstable(feature = "std_misc", + reason = "matches collection reform v2 specification, waiting for dust to settle")] +impl<'a, K, V> Entry<'a, K, V> { + /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant. + pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> { + match self { + Occupied(entry) => Ok(entry.into_mut()), + Vacant(entry) => Err(entry), + } + } +} + +impl<'a, K, V> OccupiedEntry<'a, K, V> { + /// Gets a reference to the value in the entry. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get(&self) -> &V { + self.elem.read().1 + } + + /// Gets a mutable reference to the value in the entry. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get_mut(&mut self) -> &mut V { + self.elem.read_mut().1 + } + + /// Converts the OccupiedEntry into a mutable reference to the value in the entry + /// with a lifetime bound to the map itself + #[stable(feature = "rust1", since = "1.0.0")] + pub fn into_mut(self) -> &'a mut V { + self.elem.into_mut_refs().1 + } + + /// Sets the value of the entry, and returns the entry's old value + #[stable(feature = "rust1", since = "1.0.0")] + pub fn insert(&mut self, mut value: V) -> V { + let old_value = self.get_mut(); + mem::swap(&mut value, old_value); + value + } + + /// Takes the value out of the entry, and returns it + #[stable(feature = "rust1", since = "1.0.0")] + pub fn remove(self) -> V { + pop_internal(self.elem).1 + } +} + +impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { + /// Sets the value of the entry with the VacantEntry's key, + /// and returns a mutable reference to it + #[stable(feature = "rust1", since = "1.0.0")] + pub fn insert(self, value: V) -> &'a mut V { + match self.elem { + NeqElem(bucket, ib) => { + robin_hood(bucket, ib, self.hash, self.key, value) + } + NoElem(bucket) => { + bucket.put(self.hash, self.key, value).into_mut_refs().1 + } + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl FromIterator<(K, V)> for HashMap + where K: Eq + Hash, + S: HashState + Default, + H: hash::Hasher +{ + fn from_iter>(iter: T) -> HashMap { + let lower = iter.size_hint().0; + let mut map = HashMap::with_capacity_and_hash_state(lower, + Default::default()); + map.extend(iter); + map + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Extend<(K, V)> for HashMap + where K: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + fn extend>(&mut self, iter: T) { + for (k, v) in iter { + self.insert(k, v); + } + } +} + + +/// `RandomState` is the default state for `HashMap` types. +/// +/// A particular instance `RandomState` will create the same instances of +/// `Hasher`, but the hashers created by two different `RandomState` +/// instances are unlikely to produce the same result for the same values. +#[derive(Clone)] +#[unstable(feature = "std_misc", + reason = "hashing an hash maps may be altered")] +pub struct RandomState { + k0: u64, + k1: u64, +} + +#[unstable(feature = "std_misc", + reason = "hashing an hash maps may be altered")] +impl RandomState { + /// Construct a new `RandomState` that is initialized with random keys. + #[inline] + #[allow(deprecated)] + pub fn new() -> RandomState { + let mut r = rand::thread_rng(); + RandomState { k0: r.gen(), k1: r.gen() } + } +} + +#[unstable(feature = "std_misc", + reason = "hashing an hash maps may be altered")] +impl HashState for RandomState { + type Hasher = Hasher; + fn hasher(&self) -> Hasher { + Hasher { inner: SipHasher::new_with_keys(self.k0, self.k1) } + } +} + +#[unstable(feature = "std_misc", + reason = "hashing an hash maps may be altered")] +impl Default for RandomState { + #[inline] + fn default() -> RandomState { + RandomState::new() + } +} + +/// A hasher implementation which is generated from `RandomState` instances. +/// +/// This is the default hasher used in a `HashMap` to hash keys. Types do not +/// typically declare an ability to explicitly hash into this particular type, +/// but rather in a `H: hash::Writer` type parameter. +#[unstable(feature = "std_misc", + reason = "hashing an hash maps may be altered")] +pub struct Hasher { inner: SipHasher } + +impl hash::Writer for Hasher { + fn write(&mut self, data: &[u8]) { + hash::Writer::write(&mut self.inner, data) + } +} + +impl hash::Hasher for Hasher { + type Output = u64; + fn reset(&mut self) { hash::Hasher::reset(&mut self.inner) } + fn finish(&self) -> u64 { self.inner.finish() } +} + +#[cfg(test)] +mod test_map { + use prelude::v1::*; + + use super::HashMap; + use super::Entry::{Occupied, Vacant}; + use iter::{range_inclusive, range_step_inclusive, repeat}; + use cell::RefCell; + use rand::{weak_rng, Rng}; + + #[test] + fn test_create_capacity_zero() { + let mut m = HashMap::with_capacity(0); + + assert!(m.insert(1, 1).is_none()); + + assert!(m.contains_key(&1)); + assert!(!m.contains_key(&0)); + } + + #[test] + fn test_insert() { + let mut m = HashMap::new(); + assert_eq!(m.len(), 0); + assert!(m.insert(1, 2).is_none()); + assert_eq!(m.len(), 1); + assert!(m.insert(2, 4).is_none()); + assert_eq!(m.len(), 2); + assert_eq!(*m.get(&1).unwrap(), 2); + assert_eq!(*m.get(&2).unwrap(), 4); + } + + thread_local! { static DROP_VECTOR: RefCell> = RefCell::new(Vec::new()) } + + #[derive(Hash, PartialEq, Eq)] + struct Dropable { + k: usize + } + + impl Dropable { + fn new(k: usize) -> Dropable { + DROP_VECTOR.with(|slot| { + slot.borrow_mut()[k] += 1; + }); + + Dropable { k: k } + } + } + + impl Drop for Dropable { + fn drop(&mut self) { + DROP_VECTOR.with(|slot| { + slot.borrow_mut()[self.k] -= 1; + }); + } + } + + impl Clone for Dropable { + fn clone(&self) -> Dropable { + Dropable::new(self.k) + } + } + + #[test] + fn test_drops() { + DROP_VECTOR.with(|slot| { + *slot.borrow_mut() = repeat(0).take(200).collect(); + }); + + { + let mut m = HashMap::new(); + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 0); + } + }); + + for i in 0..100 { + let d1 = Dropable::new(i); + let d2 = Dropable::new(i+100); + m.insert(d1, d2); + } + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 1); + } + }); + + for i in 0..50 { + let k = Dropable::new(i); + let v = m.remove(&k); + + assert!(v.is_some()); + + DROP_VECTOR.with(|v| { + assert_eq!(v.borrow()[i], 1); + assert_eq!(v.borrow()[i+100], 1); + }); + } + + DROP_VECTOR.with(|v| { + for i in 0..50 { + assert_eq!(v.borrow()[i], 0); + assert_eq!(v.borrow()[i+100], 0); + } + + for i in 50..100 { + assert_eq!(v.borrow()[i], 1); + assert_eq!(v.borrow()[i+100], 1); + } + }); + } + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 0); + } + }); + } + + #[test] + fn test_move_iter_drops() { + DROP_VECTOR.with(|v| { + *v.borrow_mut() = repeat(0).take(200).collect(); + }); + + let hm = { + let mut hm = HashMap::new(); + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 0); + } + }); + + for i in 0..100 { + let d1 = Dropable::new(i); + let d2 = Dropable::new(i+100); + hm.insert(d1, d2); + } + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 1); + } + }); + + hm + }; + + // By the way, ensure that cloning doesn't screw up the dropping. + drop(hm.clone()); + + { + let mut half = hm.into_iter().take(50); + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 1); + } + }); + + for _ in half.by_ref() {} + + DROP_VECTOR.with(|v| { + let nk = (0..100).filter(|&i| { + v.borrow()[i] == 1 + }).count(); + + let nv = (0..100).filter(|&i| { + v.borrow()[i+100] == 1 + }).count(); + + assert_eq!(nk, 50); + assert_eq!(nv, 50); + }); + }; + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 0); + } + }); + } + + #[test] + fn test_empty_pop() { + let mut m: HashMap = HashMap::new(); + assert_eq!(m.remove(&0), None); + } + + #[test] + fn test_lots_of_insertions() { + let mut m = HashMap::new(); + + // Try this a few times to make sure we never screw up the hashmap's + // internal state. + for _ in 0..10 { + assert!(m.is_empty()); + + for i in range_inclusive(1, 1000) { + assert!(m.insert(i, i).is_none()); + + for j in range_inclusive(1, i) { + let r = m.get(&j); + assert_eq!(r, Some(&j)); + } + + for j in range_inclusive(i+1, 1000) { + let r = m.get(&j); + assert_eq!(r, None); + } + } + + for i in range_inclusive(1001, 2000) { + assert!(!m.contains_key(&i)); + } + + // remove forwards + for i in range_inclusive(1, 1000) { + assert!(m.remove(&i).is_some()); + + for j in range_inclusive(1, i) { + assert!(!m.contains_key(&j)); + } + + for j in range_inclusive(i+1, 1000) { + assert!(m.contains_key(&j)); + } + } + + for i in range_inclusive(1, 1000) { + assert!(!m.contains_key(&i)); + } + + for i in range_inclusive(1, 1000) { + assert!(m.insert(i, i).is_none()); + } + + // remove backwards + for i in range_step_inclusive(1000, 1, -1) { + assert!(m.remove(&i).is_some()); + + for j in range_inclusive(i, 1000) { + assert!(!m.contains_key(&j)); + } + + for j in range_inclusive(1, i-1) { + assert!(m.contains_key(&j)); + } + } + } + } + + #[test] + fn test_find_mut() { + let mut m = HashMap::new(); + assert!(m.insert(1, 12).is_none()); + assert!(m.insert(2, 8).is_none()); + assert!(m.insert(5, 14).is_none()); + let new = 100; + match m.get_mut(&5) { + None => panic!(), Some(x) => *x = new + } + assert_eq!(m.get(&5), Some(&new)); + } + + #[test] + fn test_insert_overwrite() { + let mut m = HashMap::new(); + assert!(m.insert(1, 2).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert!(!m.insert(1, 3).is_none()); + assert_eq!(*m.get(&1).unwrap(), 3); + } + + #[test] + fn test_insert_conflicts() { + let mut m = HashMap::with_capacity(4); + assert!(m.insert(1, 2).is_none()); + assert!(m.insert(5, 3).is_none()); + assert!(m.insert(9, 4).is_none()); + assert_eq!(*m.get(&9).unwrap(), 4); + assert_eq!(*m.get(&5).unwrap(), 3); + assert_eq!(*m.get(&1).unwrap(), 2); + } + + #[test] + fn test_conflict_remove() { + let mut m = HashMap::with_capacity(4); + assert!(m.insert(1, 2).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert!(m.insert(5, 3).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert_eq!(*m.get(&5).unwrap(), 3); + assert!(m.insert(9, 4).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert_eq!(*m.get(&5).unwrap(), 3); + assert_eq!(*m.get(&9).unwrap(), 4); + assert!(m.remove(&1).is_some()); + assert_eq!(*m.get(&9).unwrap(), 4); + assert_eq!(*m.get(&5).unwrap(), 3); + } + + #[test] + fn test_is_empty() { + let mut m = HashMap::with_capacity(4); + assert!(m.insert(1, 2).is_none()); + assert!(!m.is_empty()); + assert!(m.remove(&1).is_some()); + assert!(m.is_empty()); + } + + #[test] + fn test_pop() { + let mut m = HashMap::new(); + m.insert(1, 2); + assert_eq!(m.remove(&1), Some(2)); + assert_eq!(m.remove(&1), None); + } + + #[test] + fn test_iterate() { + let mut m = HashMap::with_capacity(4); + for i in 0..32 { + assert!(m.insert(i, i*2).is_none()); + } + assert_eq!(m.len(), 32); + + let mut observed: u32 = 0; + + for (k, v) in &m { + assert_eq!(*v, *k * 2); + observed |= 1 << *k; + } + assert_eq!(observed, 0xFFFF_FFFF); + } + + #[test] + fn test_keys() { + let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; + let map: HashMap<_, _> = vec.into_iter().collect(); + let keys: Vec<_> = map.keys().cloned().collect(); + assert_eq!(keys.len(), 3); + assert!(keys.contains(&1)); + assert!(keys.contains(&2)); + assert!(keys.contains(&3)); + } + + #[test] + fn test_values() { + let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; + let map: HashMap<_, _> = vec.into_iter().collect(); + let values: Vec<_> = map.values().cloned().collect(); + assert_eq!(values.len(), 3); + assert!(values.contains(&'a')); + assert!(values.contains(&'b')); + assert!(values.contains(&'c')); + } + + #[test] + fn test_find() { + let mut m = HashMap::new(); + assert!(m.get(&1).is_none()); + m.insert(1, 2); + match m.get(&1) { + None => panic!(), + Some(v) => assert_eq!(*v, 2) + } + } + + #[test] + fn test_eq() { + let mut m1 = HashMap::new(); + m1.insert(1, 2); + m1.insert(2, 3); + m1.insert(3, 4); + + let mut m2 = HashMap::new(); + m2.insert(1, 2); + m2.insert(2, 3); + + assert!(m1 != m2); + + m2.insert(3, 4); + + assert_eq!(m1, m2); + } + + #[test] + fn test_show() { + let mut map = HashMap::new(); + let empty: HashMap = HashMap::new(); + + map.insert(1, 2); + map.insert(3, 4); + + let map_str = format!("{:?}", map); + + assert!(map_str == "HashMap {1: 2, 3: 4}" || + map_str == "HashMap {3: 4, 1: 2}"); + assert_eq!(format!("{:?}", empty), "HashMap {}"); + } + + #[test] + fn test_expand() { + let mut m = HashMap::new(); + + assert_eq!(m.len(), 0); + assert!(m.is_empty()); + + let mut i = 0; + let old_cap = m.table.capacity(); + while old_cap == m.table.capacity() { + m.insert(i, i); + i += 1; + } + + assert_eq!(m.len(), i); + assert!(!m.is_empty()); + } + + #[test] + fn test_behavior_resize_policy() { + let mut m = HashMap::new(); + + assert_eq!(m.len(), 0); + assert_eq!(m.table.capacity(), 0); + assert!(m.is_empty()); + + m.insert(0, 0); + m.remove(&0); + assert!(m.is_empty()); + let initial_cap = m.table.capacity(); + m.reserve(initial_cap); + let cap = m.table.capacity(); + + assert_eq!(cap, initial_cap * 2); + + let mut i = 0; + for _ in 0..cap * 3 / 4 { + m.insert(i, i); + i += 1; + } + // three quarters full + + assert_eq!(m.len(), i); + assert_eq!(m.table.capacity(), cap); + + for _ in 0..cap / 4 { + m.insert(i, i); + i += 1; + } + // half full + + let new_cap = m.table.capacity(); + assert_eq!(new_cap, cap * 2); + + for _ in 0..cap / 2 - 1 { + i -= 1; + m.remove(&i); + assert_eq!(m.table.capacity(), new_cap); + } + // A little more than one quarter full. + m.shrink_to_fit(); + assert_eq!(m.table.capacity(), cap); + // again, a little more than half full + for _ in 0..cap / 2 - 1 { + i -= 1; + m.remove(&i); + } + m.shrink_to_fit(); + + assert_eq!(m.len(), i); + assert!(!m.is_empty()); + assert_eq!(m.table.capacity(), initial_cap); + } + + #[test] + fn test_reserve_shrink_to_fit() { + let mut m = HashMap::new(); + m.insert(0, 0); + m.remove(&0); + assert!(m.capacity() >= m.len()); + for i in 0..128 { + m.insert(i, i); + } + m.reserve(256); + + let usable_cap = m.capacity(); + for i in 128..(128 + 256) { + m.insert(i, i); + assert_eq!(m.capacity(), usable_cap); + } + + for i in 100..(128 + 256) { + assert_eq!(m.remove(&i), Some(i)); + } + m.shrink_to_fit(); + + assert_eq!(m.len(), 100); + assert!(!m.is_empty()); + assert!(m.capacity() >= m.len()); + + for i in 0..100 { + assert_eq!(m.remove(&i), Some(i)); + } + m.shrink_to_fit(); + m.insert(0, 0); + + assert_eq!(m.len(), 1); + assert!(m.capacity() >= m.len()); + assert_eq!(m.remove(&0), Some(0)); + } + + #[test] + fn test_from_iter() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let map: HashMap<_, _> = xs.iter().cloned().collect(); + + for &(k, v) in &xs { + assert_eq!(map.get(&k), Some(&v)); + } + } + + #[test] + fn test_size_hint() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let map: HashMap<_, _> = xs.iter().cloned().collect(); + + let mut iter = map.iter(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.size_hint(), (3, Some(3))); + } + + #[test] + fn test_iter_len() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let map: HashMap<_, _> = xs.iter().cloned().collect(); + + let mut iter = map.iter(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.len(), 3); + } + + #[test] + fn test_mut_size_hint() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let mut map: HashMap<_, _> = xs.iter().cloned().collect(); + + let mut iter = map.iter_mut(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.size_hint(), (3, Some(3))); + } + + #[test] + fn test_iter_mut_len() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let mut map: HashMap<_, _> = xs.iter().cloned().collect(); + + let mut iter = map.iter_mut(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.len(), 3); + } + + #[test] + fn test_index() { + let mut map = HashMap::new(); + + map.insert(1, 2); + map.insert(2, 1); + map.insert(3, 4); + + assert_eq!(map[2], 1); + } + + #[test] + #[should_fail] + fn test_index_nonexistent() { + let mut map = HashMap::new(); + + map.insert(1, 2); + map.insert(2, 1); + map.insert(3, 4); + + map[4]; + } + + #[test] + fn test_entry(){ + let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)]; + + let mut map: HashMap<_, _> = xs.iter().cloned().collect(); + + // Existing key (insert) + match map.entry(1) { + Vacant(_) => unreachable!(), + Occupied(mut view) => { + assert_eq!(view.get(), &10); + assert_eq!(view.insert(100), 10); + } + } + assert_eq!(map.get(&1).unwrap(), &100); + assert_eq!(map.len(), 6); + + + // Existing key (update) + match map.entry(2) { + Vacant(_) => unreachable!(), + Occupied(mut view) => { + let v = view.get_mut(); + let new_v = (*v) * 10; + *v = new_v; + } + } + assert_eq!(map.get(&2).unwrap(), &200); + assert_eq!(map.len(), 6); + + // Existing key (take) + match map.entry(3) { + Vacant(_) => unreachable!(), + Occupied(view) => { + assert_eq!(view.remove(), 30); + } + } + assert_eq!(map.get(&3), None); + assert_eq!(map.len(), 5); + + + // Inexistent key (insert) + match map.entry(10) { + Occupied(_) => unreachable!(), + Vacant(view) => { + assert_eq!(*view.insert(1000), 1000); + } + } + assert_eq!(map.get(&10).unwrap(), &1000); + assert_eq!(map.len(), 6); + } + + #[test] + fn test_entry_take_doesnt_corrupt() { + // Test for #19292 + fn check(m: &HashMap) { + for k in m.keys() { + assert!(m.contains_key(k), + "{} is in keys() but not in the map?", k); + } + } + + let mut m = HashMap::new(); + let mut rng = weak_rng(); + + // Populate the map with some items. + for _ in 0..50 { + let x = rng.gen_range(-10, 10); + m.insert(x, ()); + } + + for i in 0..1000 { + let x = rng.gen_range(-10, 10); + match m.entry(x) { + Vacant(_) => {}, + Occupied(e) => { + println!("{}: remove {}", i, x); + e.remove(); + }, + } + + check(&m); + } + } +} diff --git a/src/libstd/collections/hash/mod.rs b/src/libstd/collections/hash/mod.rs index 47e300af26981..39c1458b72001 100644 --- a/src/libstd/collections/hash/mod.rs +++ b/src/libstd/collections/hash/mod.rs @@ -12,6 +12,14 @@ mod bench; mod table; +#[cfg(stage0)] +#[path = "map_stage0.rs"] pub mod map; +#[cfg(not(stage0))] +pub mod map; +#[cfg(stage0)] +#[path = "set_stage0.rs"] +pub mod set; +#[cfg(not(stage0))] pub mod set; pub mod state; diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 5fbbcb3b347af..7ff76452c1a80 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -17,14 +17,14 @@ use core::marker::Sized; use default::Default; use fmt::Debug; use fmt; -use hash::{self, Hash}; +use hash::Hash; use iter::{ Iterator, IntoIterator, ExactSizeIterator, IteratorExt, FromIterator, Map, Chain, Extend, }; use ops::{BitOr, BitAnd, BitXor, Sub}; use option::Option::{Some, None, self}; -use super::map::{self, HashMap, Keys, INITIAL_CAPACITY, RandomState, Hasher}; +use super::map::{self, HashMap, Keys, INITIAL_CAPACITY, RandomState}; use super::state::HashState; // Future Optimization (FIXME!) @@ -97,7 +97,7 @@ pub struct HashSet { map: HashMap } -impl + Eq> HashSet { +impl HashSet { /// Create an empty HashSet. /// /// # Example @@ -128,10 +128,8 @@ impl + Eq> HashSet { } } -impl HashSet - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl HashSet + where T: Eq + Hash, S: HashState { /// Creates a new empty hash set which will use the given hasher to hash /// keys. @@ -462,7 +460,7 @@ impl HashSet /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains(&self, value: &Q) -> bool - where Q: BorrowFrom + Hash + Eq + where Q: BorrowFrom + Hash + Eq { self.map.contains_key(value) } @@ -572,17 +570,15 @@ impl HashSet /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, value: &Q) -> bool - where Q: BorrowFrom + Hash + Eq + where Q: BorrowFrom + Hash + Eq { self.map.remove(value).is_some() } } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for HashSet - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl PartialEq for HashSet + where T: Eq + Hash, S: HashState { fn eq(&self, other: &HashSet) -> bool { if self.len() != other.len() { return false; } @@ -592,17 +588,14 @@ impl PartialEq for HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for HashSet - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl Eq for HashSet + where T: Eq + Hash, S: HashState {} #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for HashSet - where T: Eq + Hash + fmt::Debug, - S: HashState, - H: hash::Hasher +impl fmt::Debug for HashSet + where T: Eq + Hash + fmt::Debug, + S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "HashSet {{")); @@ -617,10 +610,9 @@ impl fmt::Debug for HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl FromIterator for HashSet - where T: Eq + Hash, - S: HashState + Default, - H: hash::Hasher +impl FromIterator for HashSet + where T: Eq + Hash, + S: HashState + Default, { fn from_iter>(iter: I) -> HashSet { let lower = iter.size_hint().0; @@ -631,10 +623,9 @@ impl FromIterator for HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for HashSet - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl Extend for HashSet + where T: Eq + Hash, + S: HashState, { fn extend>(&mut self, iter: I) { for k in iter { @@ -644,10 +635,9 @@ impl Extend for HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for HashSet - where T: Eq + Hash, - S: HashState + Default, - H: hash::Hasher +impl Default for HashSet + where T: Eq + Hash, + S: HashState + Default, { #[stable(feature = "rust1", since = "1.0.0")] fn default() -> HashSet { @@ -656,10 +646,9 @@ impl Default for HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T, S, H> BitOr<&'b HashSet> for &'a HashSet - where T: Eq + Hash + Clone, - S: HashState + Default, - H: hash::Hasher +impl<'a, 'b, T, S> BitOr<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, { type Output = HashSet; @@ -689,10 +678,9 @@ impl<'a, 'b, T, S, H> BitOr<&'b HashSet> for &'a HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T, S, H> BitAnd<&'b HashSet> for &'a HashSet - where T: Eq + Hash + Clone, - S: HashState + Default, - H: hash::Hasher +impl<'a, 'b, T, S> BitAnd<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, { type Output = HashSet; @@ -722,10 +710,9 @@ impl<'a, 'b, T, S, H> BitAnd<&'b HashSet> for &'a HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T, S, H> BitXor<&'b HashSet> for &'a HashSet - where T: Eq + Hash + Clone, - S: HashState + Default, - H: hash::Hasher +impl<'a, 'b, T, S> BitXor<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, { type Output = HashSet; @@ -755,10 +742,9 @@ impl<'a, 'b, T, S, H> BitXor<&'b HashSet> for &'a HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T, S, H> Sub<&'b HashSet> for &'a HashSet - where T: Eq + Hash + Clone, - S: HashState + Default, - H: hash::Hasher +impl<'a, 'b, T, S> Sub<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, { type Output = HashSet; @@ -836,10 +822,8 @@ pub struct Union<'a, T: 'a, S: 'a> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S, H> IntoIterator for &'a HashSet - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, T, S> IntoIterator for &'a HashSet + where T: Eq + Hash, S: HashState { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -850,10 +834,9 @@ impl<'a, T, S, H> IntoIterator for &'a HashSet } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for HashSet - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl IntoIterator for HashSet + where T: Eq + Hash, + S: HashState { type Item = T; type IntoIter = IntoIter; @@ -900,10 +883,8 @@ impl<'a, K> ExactSizeIterator for Drain<'a, K> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S, H> Iterator for Intersection<'a, T, S> - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, T, S> Iterator for Intersection<'a, T, S> + where T: Eq + Hash, S: HashState { type Item = &'a T; @@ -925,10 +906,8 @@ impl<'a, T, S, H> Iterator for Intersection<'a, T, S> } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S, H> Iterator for Difference<'a, T, S> - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, T, S> Iterator for Difference<'a, T, S> + where T: Eq + Hash, S: HashState { type Item = &'a T; @@ -950,10 +929,8 @@ impl<'a, T, S, H> Iterator for Difference<'a, T, S> } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S> - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S> + where T: Eq + Hash, S: HashState { type Item = &'a T; @@ -962,10 +939,8 @@ impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S> } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S, H> Iterator for Union<'a, T, S> - where T: Eq + Hash, - S: HashState, - H: hash::Hasher +impl<'a, T, S> Iterator for Union<'a, T, S> + where T: Eq + Hash, S: HashState { type Item = &'a T; diff --git a/src/libstd/collections/hash/set_stage0.rs b/src/libstd/collections/hash/set_stage0.rs new file mode 100644 index 0000000000000..3bc22236a47f2 --- /dev/null +++ b/src/libstd/collections/hash/set_stage0.rs @@ -0,0 +1,1251 @@ +// Copyright 2014 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. +// +// ignore-lexer-test FIXME #15883 + +use borrow::BorrowFrom; +use clone::Clone; +use cmp::{Eq, PartialEq}; +use core::marker::Sized; +use default::Default; +use fmt::Debug; +use fmt; +use hash::{self, Hash}; +use iter::{ + Iterator, IntoIterator, ExactSizeIterator, IteratorExt, FromIterator, Map, Chain, Extend, +}; +use ops::{BitOr, BitAnd, BitXor, Sub}; +use option::Option::{Some, None, self}; + +use super::map::{self, HashMap, Keys, INITIAL_CAPACITY, RandomState, Hasher}; +use super::state::HashState; + +// Future Optimization (FIXME!) +// ============================= +// +// Iteration over zero sized values is a noop. There is no need +// for `bucket.val` in the case of HashSet. I suppose we would need HKT +// to get rid of it properly. + +/// An implementation of a hash set using the underlying representation of a +/// HashMap where the value is (). As with the `HashMap` type, a `HashSet` +/// requires that the elements implement the `Eq` and `Hash` traits. +/// +/// # Example +/// +/// ``` +/// use std::collections::HashSet; +/// // Type inference lets us omit an explicit type signature (which +/// // would be `HashSet<&str>` in this example). +/// let mut books = HashSet::new(); +/// +/// // Add some books. +/// books.insert("A Dance With Dragons"); +/// books.insert("To Kill a Mockingbird"); +/// books.insert("The Odyssey"); +/// books.insert("The Great Gatsby"); +/// +/// // Check for a specific one. +/// if !books.contains(&("The Winds of Winter")) { +/// println!("We have {} books, but The Winds of Winter ain't one.", +/// books.len()); +/// } +/// +/// // Remove a book. +/// books.remove(&"The Odyssey"); +/// +/// // Iterate over everything. +/// for book in books.iter() { +/// println!("{}", *book); +/// } +/// ``` +/// +/// The easiest way to use `HashSet` with a custom type is to derive +/// `Eq` and `Hash`. We must also derive `PartialEq`, this will in the +/// future be implied by `Eq`. +/// +/// ``` +/// use std::collections::HashSet; +/// #[derive(Hash, Eq, PartialEq, Debug)] +/// struct Viking<'a> { +/// name: &'a str, +/// power: usize, +/// } +/// +/// let mut vikings = HashSet::new(); +/// +/// vikings.insert(Viking { name: "Einar", power: 9 }); +/// vikings.insert(Viking { name: "Einar", power: 9 }); +/// vikings.insert(Viking { name: "Olaf", power: 4 }); +/// vikings.insert(Viking { name: "Harald", power: 8 }); +/// +/// // Use derived implementation to print the vikings. +/// for x in vikings.iter() { +/// println!("{:?}", x); +/// } +/// ``` +#[derive(Clone)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct HashSet { + map: HashMap +} + +impl + Eq> HashSet { + /// Create an empty HashSet. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let mut set: HashSet = HashSet::new(); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn new() -> HashSet { + HashSet::with_capacity(INITIAL_CAPACITY) + } + + /// Create an empty HashSet with space for at least `n` elements in + /// the hash table. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let mut set: HashSet = HashSet::with_capacity(10); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn with_capacity(capacity: usize) -> HashSet { + HashSet { map: HashMap::with_capacity(capacity) } + } +} + +impl HashSet + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + /// Creates a new empty hash set which will use the given hasher to hash + /// keys. + /// + /// The hash set is also created with the default initial capacity. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// use std::collections::hash_map::RandomState; + /// + /// let s = RandomState::new(); + /// let mut set = HashSet::with_hash_state(s); + /// set.insert(2); + /// ``` + #[inline] + #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")] + pub fn with_hash_state(hash_state: S) -> HashSet { + HashSet::with_capacity_and_hash_state(INITIAL_CAPACITY, hash_state) + } + + /// Create an empty HashSet with space for at least `capacity` + /// elements in the hash table, using `hasher` to hash the keys. + /// + /// Warning: `hasher` is normally randomly generated, and + /// is designed to allow `HashSet`s to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// use std::collections::hash_map::RandomState; + /// + /// let s = RandomState::new(); + /// let mut set = HashSet::with_capacity_and_hash_state(10, s); + /// set.insert(1); + /// ``` + #[inline] + #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")] + pub fn with_capacity_and_hash_state(capacity: usize, hash_state: S) + -> HashSet { + HashSet { + map: HashMap::with_capacity_and_hash_state(capacity, hash_state), + } + } + + /// Returns the number of elements the set can hold without reallocating. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let set: HashSet = HashSet::with_capacity(100); + /// assert!(set.capacity() >= 100); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn capacity(&self) -> usize { + self.map.capacity() + } + + /// Reserves capacity for at least `additional` more elements to be inserted + /// in the `HashSet`. The collection may reserve more space to avoid + /// frequent reallocations. + /// + /// # Panics + /// + /// Panics if the new allocation size overflows `usize`. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let mut set: HashSet = HashSet::new(); + /// set.reserve(10); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn reserve(&mut self, additional: usize) { + self.map.reserve(additional) + } + + /// Shrinks the capacity of the set as much as possible. It will drop + /// down as much as possible while maintaining the internal rules + /// and possibly leaving some space in accordance with the resize policy. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut set: HashSet = HashSet::with_capacity(100); + /// set.insert(1); + /// set.insert(2); + /// assert!(set.capacity() >= 100); + /// set.shrink_to_fit(); + /// assert!(set.capacity() >= 2); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn shrink_to_fit(&mut self) { + self.map.shrink_to_fit() + } + + /// An iterator visiting all elements in arbitrary order. + /// Iterator element type is &'a T. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let mut set = HashSet::new(); + /// set.insert("a"); + /// set.insert("b"); + /// + /// // Will print in an arbitrary order. + /// for x in set.iter() { + /// println!("{}", x); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn iter(&self) -> Iter { + Iter { iter: self.map.keys() } + } + + /// Creates a consuming iterator, that is, one that moves each value out + /// of the set in arbitrary order. The set cannot be used after calling + /// this. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let mut set = HashSet::new(); + /// set.insert("a".to_string()); + /// set.insert("b".to_string()); + /// + /// // Not possible to collect to a Vec with a regular `.iter()`. + /// let v: Vec = set.into_iter().collect(); + /// + /// // Will print in an arbitrary order. + /// for x in v.iter() { + /// println!("{}", x); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn into_iter(self) -> IntoIter { + fn first((a, _): (A, B)) -> A { a } + let first: fn((T, ())) -> T = first; + + IntoIter { iter: self.map.into_iter().map(first) } + } + + /// Visit the values representing the difference. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let a: HashSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: HashSet = [4, 2, 3, 4].iter().map(|&x| x).collect(); + /// + /// // Can be seen as `a - b`. + /// for x in a.difference(&b) { + /// println!("{}", x); // Print 1 + /// } + /// + /// let diff: HashSet = a.difference(&b).map(|&x| x).collect(); + /// assert_eq!(diff, [1].iter().map(|&x| x).collect()); + /// + /// // Note that difference is not symmetric, + /// // and `b - a` means something else: + /// let diff: HashSet = b.difference(&a).map(|&x| x).collect(); + /// assert_eq!(diff, [4].iter().map(|&x| x).collect()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn difference<'a>(&'a self, other: &'a HashSet) -> Difference<'a, T, S> { + Difference { + iter: self.iter(), + other: other, + } + } + + /// Visit the values representing the symmetric difference. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let a: HashSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: HashSet = [4, 2, 3, 4].iter().map(|&x| x).collect(); + /// + /// // Print 1, 4 in arbitrary order. + /// for x in a.symmetric_difference(&b) { + /// println!("{}", x); + /// } + /// + /// let diff1: HashSet = a.symmetric_difference(&b).map(|&x| x).collect(); + /// let diff2: HashSet = b.symmetric_difference(&a).map(|&x| x).collect(); + /// + /// assert_eq!(diff1, diff2); + /// assert_eq!(diff1, [1, 4].iter().map(|&x| x).collect()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet) + -> SymmetricDifference<'a, T, S> { + SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) } + } + + /// Visit the values representing the intersection. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let a: HashSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: HashSet = [4, 2, 3, 4].iter().map(|&x| x).collect(); + /// + /// // Print 2, 3 in arbitrary order. + /// for x in a.intersection(&b) { + /// println!("{}", x); + /// } + /// + /// let diff: HashSet = a.intersection(&b).map(|&x| x).collect(); + /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn intersection<'a>(&'a self, other: &'a HashSet) -> Intersection<'a, T, S> { + Intersection { + iter: self.iter(), + other: other, + } + } + + /// Visit the values representing the union. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let a: HashSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: HashSet = [4, 2, 3, 4].iter().map(|&x| x).collect(); + /// + /// // Print 1, 2, 3, 4 in arbitrary order. + /// for x in a.union(&b) { + /// println!("{}", x); + /// } + /// + /// let diff: HashSet = a.union(&b).map(|&x| x).collect(); + /// assert_eq!(diff, [1, 2, 3, 4].iter().map(|&x| x).collect()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn union<'a>(&'a self, other: &'a HashSet) -> Union<'a, T, S> { + Union { iter: self.iter().chain(other.difference(self)) } + } + + /// Return the number of elements in the set + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut v = HashSet::new(); + /// assert_eq!(v.len(), 0); + /// v.insert(1); + /// assert_eq!(v.len(), 1); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn len(&self) -> usize { self.map.len() } + + /// Returns true if the set contains no elements + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut v = HashSet::new(); + /// assert!(v.is_empty()); + /// v.insert(1); + /// assert!(!v.is_empty()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_empty(&self) -> bool { self.map.len() == 0 } + + /// Clears the set, returning all elements in an iterator. + #[inline] + #[unstable(feature = "std_misc", + reason = "matches collection reform specification, waiting for dust to settle")] + pub fn drain(&mut self) -> Drain { + fn first((a, _): (A, B)) -> A { a } + let first: fn((T, ())) -> T = first; // coerce to fn pointer + + Drain { iter: self.map.drain().map(first) } + } + + /// Clears the set, removing all values. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut v = HashSet::new(); + /// v.insert(1); + /// v.clear(); + /// assert!(v.is_empty()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn clear(&mut self) { self.map.clear() } + + /// Returns `true` if the set contains a value. + /// + /// The value may be any borrowed form of the set's value type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the value type. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let set: HashSet<_> = [1, 2, 3].iter().cloned().collect(); + /// assert_eq!(set.contains(&1), true); + /// assert_eq!(set.contains(&4), false); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn contains(&self, value: &Q) -> bool + where Q: BorrowFrom + Hash + Eq + { + self.map.contains_key(value) + } + + /// Returns `true` if the set has no elements in common with `other`. + /// This is equivalent to checking for an empty intersection. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect(); + /// let mut b = HashSet::new(); + /// + /// assert_eq!(a.is_disjoint(&b), true); + /// b.insert(4); + /// assert_eq!(a.is_disjoint(&b), true); + /// b.insert(1); + /// assert_eq!(a.is_disjoint(&b), false); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_disjoint(&self, other: &HashSet) -> bool { + self.iter().all(|v| !other.contains(v)) + } + + /// Returns `true` if the set is a subset of another. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let sup: HashSet<_> = [1, 2, 3].iter().cloned().collect(); + /// let mut set = HashSet::new(); + /// + /// assert_eq!(set.is_subset(&sup), true); + /// set.insert(2); + /// assert_eq!(set.is_subset(&sup), true); + /// set.insert(4); + /// assert_eq!(set.is_subset(&sup), false); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_subset(&self, other: &HashSet) -> bool { + self.iter().all(|v| other.contains(v)) + } + + /// Returns `true` if the set is a superset of another. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let sub: HashSet<_> = [1, 2].iter().cloned().collect(); + /// let mut set = HashSet::new(); + /// + /// assert_eq!(set.is_superset(&sub), false); + /// + /// set.insert(0); + /// set.insert(1); + /// assert_eq!(set.is_superset(&sub), false); + /// + /// set.insert(2); + /// assert_eq!(set.is_superset(&sub), true); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_superset(&self, other: &HashSet) -> bool { + other.is_subset(self) + } + + /// Adds a value to the set. Returns `true` if the value was not already + /// present in the set. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut set = HashSet::new(); + /// + /// assert_eq!(set.insert(2), true); + /// assert_eq!(set.insert(2), false); + /// assert_eq!(set.len(), 1); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() } + + /// Removes a value from the set. Returns `true` if the value was + /// present in the set. + /// + /// The value may be any borrowed form of the set's value type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the value type. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut set = HashSet::new(); + /// + /// set.insert(2); + /// assert_eq!(set.remove(&2), true); + /// assert_eq!(set.remove(&2), false); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn remove(&mut self, value: &Q) -> bool + where Q: BorrowFrom + Hash + Eq + { + self.map.remove(value).is_some() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl PartialEq for HashSet + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + fn eq(&self, other: &HashSet) -> bool { + if self.len() != other.len() { return false; } + + self.iter().all(|key| other.contains(key)) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Eq for HashSet + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{} + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Debug for HashSet + where T: Eq + Hash + fmt::Debug, + S: HashState, + H: hash::Hasher +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(write!(f, "HashSet {{")); + + for (i, x) in self.iter().enumerate() { + if i != 0 { try!(write!(f, ", ")); } + try!(write!(f, "{:?}", *x)); + } + + write!(f, "}}") + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl FromIterator for HashSet + where T: Eq + Hash, + S: HashState + Default, + H: hash::Hasher +{ + fn from_iter>(iter: I) -> HashSet { + let lower = iter.size_hint().0; + let mut set = HashSet::with_capacity_and_hash_state(lower, Default::default()); + set.extend(iter); + set + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Extend for HashSet + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + fn extend>(&mut self, iter: I) { + for k in iter { + self.insert(k); + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Default for HashSet + where T: Eq + Hash, + S: HashState + Default, + H: hash::Hasher +{ + #[stable(feature = "rust1", since = "1.0.0")] + fn default() -> HashSet { + HashSet::with_hash_state(Default::default()) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b, T, S, H> BitOr<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, + H: hash::Hasher +{ + type Output = HashSet; + + /// Returns the union of `self` and `rhs` as a new `HashSet`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect(); + /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect(); + /// + /// let set = &a | &b; + /// + /// let mut i = 0; + /// let expected = [1, 2, 3, 4, 5]; + /// for x in set.iter() { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn bitor(self, rhs: &HashSet) -> HashSet { + self.union(rhs).cloned().collect() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b, T, S, H> BitAnd<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, + H: hash::Hasher +{ + type Output = HashSet; + + /// Returns the intersection of `self` and `rhs` as a new `HashSet`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect(); + /// let b: HashSet<_> = vec![2, 3, 4].into_iter().collect(); + /// + /// let set = &a & &b; + /// + /// let mut i = 0; + /// let expected = [2, 3]; + /// for x in set.iter() { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn bitand(self, rhs: &HashSet) -> HashSet { + self.intersection(rhs).cloned().collect() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b, T, S, H> BitXor<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, + H: hash::Hasher +{ + type Output = HashSet; + + /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect(); + /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect(); + /// + /// let set = &a ^ &b; + /// + /// let mut i = 0; + /// let expected = [1, 2, 4, 5]; + /// for x in set.iter() { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn bitxor(self, rhs: &HashSet) -> HashSet { + self.symmetric_difference(rhs).cloned().collect() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b, T, S, H> Sub<&'b HashSet> for &'a HashSet + where T: Eq + Hash + Clone, + S: HashState + Default, + H: hash::Hasher +{ + type Output = HashSet; + + /// Returns the difference of `self` and `rhs` as a new `HashSet`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect(); + /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect(); + /// + /// let set = &a - &b; + /// + /// let mut i = 0; + /// let expected = [1, 2]; + /// for x in set.iter() { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn sub(self, rhs: &HashSet) -> HashSet { + self.difference(rhs).cloned().collect() + } +} + +/// HashSet iterator +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Iter<'a, K: 'a> { + iter: Keys<'a, K, ()> +} + +/// HashSet move iterator +#[stable(feature = "rust1", since = "1.0.0")] +pub struct IntoIter { + iter: Map, fn((K, ())) -> K> +} + +/// HashSet drain iterator +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Drain<'a, K: 'a> { + iter: Map, fn((K, ())) -> K>, +} + +/// Intersection iterator +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Intersection<'a, T: 'a, S: 'a> { + // iterator of the first set + iter: Iter<'a, T>, + // the second set + other: &'a HashSet, +} + +/// Difference iterator +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Difference<'a, T: 'a, S: 'a> { + // iterator of the first set + iter: Iter<'a, T>, + // the second set + other: &'a HashSet, +} + +/// Symmetric difference iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct SymmetricDifference<'a, T: 'a, S: 'a> { + iter: Chain, Difference<'a, T, S>> +} + +/// Set union iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Union<'a, T: 'a, S: 'a> { + iter: Chain, Difference<'a, T, S>> +} + +impl<'a, T, S, H> IntoIterator for &'a HashSet + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = &'a T; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } +} + +impl IntoIterator for HashSet + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = T; + type IntoIter = IntoIter; + + fn into_iter(self) -> IntoIter { + self.into_iter() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K> Iterator for Iter<'a, K> { + type Item = &'a K; + + fn next(&mut self) -> Option<&'a K> { self.iter.next() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K> ExactSizeIterator for Iter<'a, K> { + fn len(&self) -> usize { self.iter.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for IntoIter { + type Item = K; + + fn next(&mut self) -> Option { self.iter.next() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for IntoIter { + fn len(&self) -> usize { self.iter.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K> Iterator for Drain<'a, K> { + type Item = K; + + fn next(&mut self) -> Option { self.iter.next() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K> ExactSizeIterator for Drain<'a, K> { + fn len(&self) -> usize { self.iter.len() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, S, H> Iterator for Intersection<'a, T, S> + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = &'a T; + + fn next(&mut self) -> Option<&'a T> { + loop { + match self.iter.next() { + None => return None, + Some(elt) => if self.other.contains(elt) { + return Some(elt) + }, + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, S, H> Iterator for Difference<'a, T, S> + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = &'a T; + + fn next(&mut self) -> Option<&'a T> { + loop { + match self.iter.next() { + None => return None, + Some(elt) => if !self.other.contains(elt) { + return Some(elt) + }, + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S> + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = &'a T; + + fn next(&mut self) -> Option<&'a T> { self.iter.next() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, S, H> Iterator for Union<'a, T, S> + where T: Eq + Hash, + S: HashState, + H: hash::Hasher +{ + type Item = &'a T; + + fn next(&mut self) -> Option<&'a T> { self.iter.next() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} + +#[cfg(test)] +mod test_set { + use prelude::v1::*; + + use super::HashSet; + + #[test] + fn test_disjoint() { + let mut xs = HashSet::new(); + let mut ys = HashSet::new(); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(xs.insert(5)); + assert!(ys.insert(11)); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(xs.insert(7)); + assert!(xs.insert(19)); + assert!(xs.insert(4)); + assert!(ys.insert(2)); + assert!(ys.insert(-11)); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(ys.insert(7)); + assert!(!xs.is_disjoint(&ys)); + assert!(!ys.is_disjoint(&xs)); + } + + #[test] + fn test_subset_and_superset() { + let mut a = HashSet::new(); + assert!(a.insert(0)); + assert!(a.insert(5)); + assert!(a.insert(11)); + assert!(a.insert(7)); + + let mut b = HashSet::new(); + assert!(b.insert(0)); + assert!(b.insert(7)); + assert!(b.insert(19)); + assert!(b.insert(250)); + assert!(b.insert(11)); + assert!(b.insert(200)); + + assert!(!a.is_subset(&b)); + assert!(!a.is_superset(&b)); + assert!(!b.is_subset(&a)); + assert!(!b.is_superset(&a)); + + assert!(b.insert(5)); + + assert!(a.is_subset(&b)); + assert!(!a.is_superset(&b)); + assert!(!b.is_subset(&a)); + assert!(b.is_superset(&a)); + } + + #[test] + fn test_iterate() { + let mut a = HashSet::new(); + for i in 0..32 { + assert!(a.insert(i)); + } + let mut observed: u32 = 0; + for k in &a { + observed |= 1 << *k; + } + assert_eq!(observed, 0xFFFF_FFFF); + } + + #[test] + fn test_intersection() { + let mut a = HashSet::new(); + let mut b = HashSet::new(); + + assert!(a.insert(11)); + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(77)); + assert!(a.insert(103)); + assert!(a.insert(5)); + assert!(a.insert(-5)); + + assert!(b.insert(2)); + assert!(b.insert(11)); + assert!(b.insert(77)); + assert!(b.insert(-9)); + assert!(b.insert(-42)); + assert!(b.insert(5)); + assert!(b.insert(3)); + + let mut i = 0; + let expected = [3, 5, 11, 77]; + for x in a.intersection(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + } + + #[test] + fn test_difference() { + let mut a = HashSet::new(); + let mut b = HashSet::new(); + + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(5)); + assert!(a.insert(9)); + assert!(a.insert(11)); + + assert!(b.insert(3)); + assert!(b.insert(9)); + + let mut i = 0; + let expected = [1, 5, 11]; + for x in a.difference(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + } + + #[test] + fn test_symmetric_difference() { + let mut a = HashSet::new(); + let mut b = HashSet::new(); + + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(5)); + assert!(a.insert(9)); + assert!(a.insert(11)); + + assert!(b.insert(-2)); + assert!(b.insert(3)); + assert!(b.insert(9)); + assert!(b.insert(14)); + assert!(b.insert(22)); + + let mut i = 0; + let expected = [-2, 1, 5, 11, 14, 22]; + for x in a.symmetric_difference(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + } + + #[test] + fn test_union() { + let mut a = HashSet::new(); + let mut b = HashSet::new(); + + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(5)); + assert!(a.insert(9)); + assert!(a.insert(11)); + assert!(a.insert(16)); + assert!(a.insert(19)); + assert!(a.insert(24)); + + assert!(b.insert(-2)); + assert!(b.insert(1)); + assert!(b.insert(5)); + assert!(b.insert(9)); + assert!(b.insert(13)); + assert!(b.insert(19)); + + let mut i = 0; + let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]; + for x in a.union(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + } + + #[test] + fn test_from_iter() { + let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + + let set: HashSet<_> = xs.iter().cloned().collect(); + + for x in &xs { + assert!(set.contains(x)); + } + } + + #[test] + fn test_move_iter() { + let hs = { + let mut hs = HashSet::new(); + + hs.insert('a'); + hs.insert('b'); + + hs + }; + + let v = hs.into_iter().collect::>(); + assert!(['a', 'b'] == v || ['b', 'a'] == v); + } + + #[test] + fn test_eq() { + // These constants once happened to expose a bug in insert(). + // I'm keeping them around to prevent a regression. + let mut s1 = HashSet::new(); + + s1.insert(1); + s1.insert(2); + s1.insert(3); + + let mut s2 = HashSet::new(); + + s2.insert(1); + s2.insert(2); + + assert!(s1 != s2); + + s2.insert(3); + + assert_eq!(s1, s2); + } + + #[test] + fn test_show() { + let mut set = HashSet::new(); + let empty = HashSet::::new(); + + set.insert(1); + set.insert(2); + + let set_str = format!("{:?}", set); + + assert!(set_str == "HashSet {1, 2}" || set_str == "HashSet {2, 1}"); + assert_eq!(format!("{:?}", empty), "HashSet {}"); + } + + #[test] + fn test_trivial_drain() { + let mut s = HashSet::::new(); + for _ in s.drain() {} + assert!(s.is_empty()); + drop(s); + + let mut s = HashSet::::new(); + drop(s.drain()); + assert!(s.is_empty()); + } + + #[test] + fn test_drain() { + let mut s: HashSet<_> = (1..100).collect(); + + // try this a bunch of times to make sure we don't screw up internal state. + for _ in 0..20 { + assert_eq!(s.len(), 99); + + { + let mut last_i = 0; + let mut d = s.drain(); + for (i, x) in d.by_ref().take(50).enumerate() { + last_i = i; + assert!(x != 0); + } + assert_eq!(last_i, 49); + } + + for _ in &s { panic!("s should be empty!"); } + + // reset to try again. + s.extend(1..100); + } + } +} diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 0bb6bd4cf356a..7114da93ea027 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -141,6 +141,7 @@ impl SafeHash { /// We need to remove hashes of 0. That's reserved for empty buckets. /// This function wraps up `hash_keyed` to be the only way outside this /// module to generate a SafeHash. +#[cfg(stage0)] pub fn make_hash(hash_state: &S, t: &T) -> SafeHash where T: Hash, S: HashState, @@ -155,6 +156,22 @@ pub fn make_hash(hash_state: &S, t: &T) -> SafeHash SafeHash { hash: 0x8000_0000_0000_0000 | state.finish() } } +/// We need to remove hashes of 0. That's reserved for empty buckets. +/// This function wraps up `hash_keyed` to be the only way outside this +/// module to generate a SafeHash. +#[cfg(not(stage0))] +pub fn make_hash(hash_state: &S, t: &T) -> SafeHash + where T: Hash, S: HashState +{ + let mut state = hash_state.hasher(); + t.hash(&mut state); + // We need to avoid 0u64 in order to prevent collisions with + // EMPTY_HASH. We can maintain our precious uniform distribution + // of initial indexes by unconditionally setting the MSB, + // effectively reducing 64-bits hashes to 63 bits. + SafeHash { hash: 0x8000_0000_0000_0000 | state.finish() } +} + // `replace` casts a `*u64` to a `*SafeHash`. Since we statically // ensure that a `FullBucket` points to an index with a non-zero hash, // and a `SafeHash` is just a `u64` with a different name, this is diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 1d14b141778f0..4e50e1c293fb5 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -40,7 +40,8 @@ use mem; use string::{String, CowString}; use ops; use cmp; -use hash::{Hash, Hasher, Writer}; +use hash::{Hash, Hasher}; +#[cfg(stage0)] use hash::Writer; use old_path::{Path, GenericPath}; use sys::os_str::{Buf, Slice}; @@ -162,12 +163,21 @@ impl Ord for OsString { } } +#[cfg(stage0)] impl<'a, S: Hasher + Writer> Hash for OsString { #[inline] fn hash(&self, state: &mut S) { (&**self).hash(state) } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for OsString { + #[inline] + fn hash(&self, state: &mut H) { + (&**self).hash(state) + } +} impl OsStr { /// Coerce directly from a `&str` slice to a `&OsStr` slice. @@ -253,12 +263,21 @@ impl Ord for OsStr { fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) } } +#[cfg(stage0)] impl<'a, S: Hasher + Writer> Hash for OsStr { #[inline] fn hash(&self, state: &mut S) { self.bytes().hash(state) } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for OsStr { + #[inline] + fn hash(&self, state: &mut H) { + self.bytes().hash(state) + } +} impl Debug for OsStr { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 66d4d34f8eb54..51944adf3b403 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -147,6 +147,7 @@ impl PartialEq for Repr { } impl Eq for Repr {} +#[cfg(stage0)] impl hash::Hash for Repr { fn hash(&self, s: &mut S) { match *self { @@ -160,6 +161,21 @@ impl hash::Hash for Repr { } } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl hash::Hash for Repr { + fn hash(&self, s: &mut H) { + match *self { + Repr::V4(ref a) => { + (a.sin_family, a.sin_port, a.sin_addr.s_addr).hash(s) + } + Repr::V6(ref a) => { + (a.sin6_family, a.sin6_port, &a.sin6_addr.s6_addr, + a.sin6_flowinfo, a.sin6_scope_id).hash(s) + } + } + } +} /// A trait for objects which can be converted or resolved to one or more /// `SocketAddr` values. diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 08f7a6e2e9636..571a1b03ef07f 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -189,11 +189,19 @@ impl PartialEq for Ipv4Addr { } impl Eq for Ipv4Addr {} +#[cfg(stage0)] impl hash::Hash for Ipv4Addr { fn hash(&self, s: &mut S) { self.inner.s_addr.hash(s) } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl hash::Hash for Ipv4Addr { + fn hash(&self, s: &mut H) { + self.inner.s_addr.hash(s) + } +} impl PartialOrd for Ipv4Addr { fn partial_cmp(&self, other: &Ipv4Addr) -> Option { @@ -421,11 +429,19 @@ impl PartialEq for Ipv6Addr { } impl Eq for Ipv6Addr {} +#[cfg(stage0)] impl hash::Hash for Ipv6Addr { fn hash(&self, s: &mut S) { self.inner.s6_addr.hash(s) } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl hash::Hash for Ipv6Addr { + fn hash(&self, s: &mut H) { + self.inner.s6_addr.hash(s) + } +} impl PartialOrd for Ipv6Addr { fn partial_cmp(&self, other: &Ipv6Addr) -> Option { diff --git a/src/libstd/old_path/posix.rs b/src/libstd/old_path/posix.rs index 440d17cfd50f7..c57cd584a4425 100644 --- a/src/libstd/old_path/posix.rs +++ b/src/libstd/old_path/posix.rs @@ -100,12 +100,21 @@ impl FromStr for Path { #[derive(Debug, Clone, PartialEq, Copy)] pub struct ParsePathError; +#[cfg(stage0)] impl hash::Hash for Path { #[inline] fn hash(&self, state: &mut S) { self.repr.hash(state) } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl hash::Hash for Path { + #[inline] + fn hash(&self, state: &mut H) { + self.repr.hash(state) + } +} impl BytesContainer for Path { #[inline] diff --git a/src/libstd/old_path/windows.rs b/src/libstd/old_path/windows.rs index 07c5e10992b63..859499d187d4c 100644 --- a/src/libstd/old_path/windows.rs +++ b/src/libstd/old_path/windows.rs @@ -127,6 +127,7 @@ impl FromStr for Path { #[derive(Debug, Clone, PartialEq, Copy)] pub struct ParsePathError; +#[cfg(stage0)] impl hash::Hash for Path { #[cfg(not(test))] #[inline] @@ -140,6 +141,21 @@ impl hash::Hash for Path { // No-op because the `hash` implementation will be wrong. } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl hash::Hash for Path { + #[cfg(not(test))] + #[inline] + fn hash(&self, state: &mut H) { + self.repr.hash(state) + } + + #[cfg(test)] + #[inline] + fn hash(&self, _: &mut H) { + // No-op because the `hash` implementation will be wrong. + } +} impl BytesContainer for Path { #[inline] diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index b610f6c370bb3..c4f2de7fb45cb 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -31,7 +31,8 @@ use ascii::*; use borrow::Cow; use cmp; use fmt; -use hash::{Hash, Writer, Hasher}; +use hash::{Hash, Hasher}; +#[cfg(stage0)] use hash::Writer; use iter::FromIterator; use mem; use num::Int; @@ -794,13 +795,22 @@ impl<'a> Iterator for EncodeWide<'a> { } } +#[cfg(stage0)] impl Hash for CodePoint { #[inline] fn hash(&self, state: &mut S) { self.value.hash(state) } } +#[cfg(not(stage0))] +impl Hash for CodePoint { + #[inline] + fn hash(&self, state: &mut H) { + self.value.hash(state) + } +} +#[cfg(stage0)] impl Hash for Wtf8Buf { #[inline] fn hash(&self, state: &mut S) { @@ -808,7 +818,16 @@ impl Hash for Wtf8Buf { 0xfeu8.hash(state) } } +#[cfg(not(stage0))] +impl Hash for Wtf8Buf { + #[inline] + fn hash(&self, state: &mut H) { + state.write(&self.bytes); + 0xfeu8.hash(state) + } +} +#[cfg(stage0)] impl<'a, S: Writer + Hasher> Hash for Wtf8 { #[inline] fn hash(&self, state: &mut S) { @@ -816,6 +835,14 @@ impl<'a, S: Writer + Hasher> Hash for Wtf8 { 0xfeu8.hash(state) } } +#[cfg(not(stage0))] +impl Hash for Wtf8 { + #[inline] + fn hash(&self, state: &mut H) { + state.write(&self.bytes); + 0xfeu8.hash(state) + } +} impl AsciiExt for Wtf8 { type Owned = Wtf8Buf; diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index f954024b0e9e3..b30ac889120c2 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -12,6 +12,7 @@ use prelude::v1::*; use self::Req::*; use collections::HashMap; +#[cfg(stage0)] use collections::hash_map::Hasher; use ffi::CString; use hash::Hash; @@ -63,6 +64,7 @@ impl Process { mkerr_libc(r) } + #[cfg(stage0)] pub fn spawn(cfg: &C, in_fd: Option

, out_fd: Option

, err_fd: Option

) -> IoResult @@ -278,6 +280,214 @@ impl Process { }) }) } + #[cfg(not(stage0))] + pub fn spawn(cfg: &C, in_fd: Option

, + out_fd: Option

, err_fd: Option

) + -> IoResult + where C: ProcessConfig, P: AsInner, + K: BytesContainer + Eq + Hash, V: BytesContainer + { + use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp}; + use libc::funcs::bsd44::getdtablesize; + + mod rustrt { + extern { + pub fn rust_unset_sigprocmask(); + } + } + + unsafe fn set_cloexec(fd: c_int) { + let ret = c::ioctl(fd, c::FIOCLEX); + assert_eq!(ret, 0); + } + + let dirp = cfg.cwd().map(|c| c.as_ptr()).unwrap_or(ptr::null()); + + // temporary until unboxed closures land + let cfg = unsafe { + mem::transmute::<&ProcessConfig,&'static ProcessConfig>(cfg) + }; + + with_envp(cfg.env(), move|envp: *const c_void| { + with_argv(cfg.program(), cfg.args(), move|argv: *const *const libc::c_char| unsafe { + let (input, mut output) = try!(sys::os::pipe()); + + // We may use this in the child, so perform allocations before the + // fork + let devnull = b"/dev/null\0"; + + set_cloexec(output.fd()); + + let pid = fork(); + if pid < 0 { + return Err(super::last_error()) + } else if pid > 0 { + #[inline] + fn combine(arr: &[u8]) -> i32 { + let a = arr[0] as u32; + let b = arr[1] as u32; + let c = arr[2] as u32; + let d = arr[3] as u32; + + ((a << 24) | (b << 16) | (c << 8) | (d << 0)) as i32 + } + + let p = Process{ pid: pid }; + drop(output); + let mut bytes = [0; 8]; + return match input.read(&mut bytes) { + Ok(8) => { + assert!(combine(CLOEXEC_MSG_FOOTER) == combine(&bytes[4.. 8]), + "Validation on the CLOEXEC pipe failed: {:?}", bytes); + let errno = combine(&bytes[0.. 4]); + assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic"); + Err(super::decode_error(errno)) + } + Err(ref e) if e.kind == EndOfFile => Ok(p), + Err(e) => { + assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic"); + panic!("the CLOEXEC pipe failed: {:?}", e) + }, + Ok(..) => { // pipe I/O up to PIPE_BUF bytes should be atomic + assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic"); + panic!("short read on the CLOEXEC pipe") + } + }; + } + + // And at this point we've reached a special time in the life of the + // child. The child must now be considered hamstrung and unable to + // do anything other than syscalls really. Consider the following + // scenario: + // + // 1. Thread A of process 1 grabs the malloc() mutex + // 2. Thread B of process 1 forks(), creating thread C + // 3. Thread C of process 2 then attempts to malloc() + // 4. The memory of process 2 is the same as the memory of + // process 1, so the mutex is locked. + // + // This situation looks a lot like deadlock, right? It turns out + // that this is what pthread_atfork() takes care of, which is + // presumably implemented across platforms. The first thing that + // threads to *before* forking is to do things like grab the malloc + // mutex, and then after the fork they unlock it. + // + // Despite this information, libnative's spawn has been witnessed to + // deadlock on both OSX and FreeBSD. I'm not entirely sure why, but + // all collected backtraces point at malloc/free traffic in the + // child spawned process. + // + // For this reason, the block of code below should contain 0 + // invocations of either malloc of free (or their related friends). + // + // As an example of not having malloc/free traffic, we don't close + // this file descriptor by dropping the FileDesc (which contains an + // allocation). Instead we just close it manually. This will never + // have the drop glue anyway because this code never returns (the + // child will either exec() or invoke libc::exit) + let _ = libc::close(input.fd()); + + fn fail(output: &mut FileDesc) -> ! { + let errno = sys::os::errno() as u32; + let bytes = [ + (errno >> 24) as u8, + (errno >> 16) as u8, + (errno >> 8) as u8, + (errno >> 0) as u8, + CLOEXEC_MSG_FOOTER[0], CLOEXEC_MSG_FOOTER[1], + CLOEXEC_MSG_FOOTER[2], CLOEXEC_MSG_FOOTER[3] + ]; + // pipe I/O up to PIPE_BUF bytes should be atomic + assert!(output.write(&bytes).is_ok()); + unsafe { libc::_exit(1) } + } + + rustrt::rust_unset_sigprocmask(); + + // If a stdio file descriptor is set to be ignored (via a -1 file + // descriptor), then we don't actually close it, but rather open + // up /dev/null into that file descriptor. Otherwise, the first file + // descriptor opened up in the child would be numbered as one of the + // stdio file descriptors, which is likely to wreak havoc. + let setup = |src: Option

, dst: c_int| { + let src = match src { + None => { + let flags = if dst == libc::STDIN_FILENO { + libc::O_RDONLY + } else { + libc::O_RDWR + }; + libc::open(devnull.as_ptr() as *const _, flags, 0) + } + Some(obj) => { + let fd = obj.as_inner().fd(); + // Leak the memory and the file descriptor. We're in the + // child now an all our resources are going to be + // cleaned up very soon + mem::forget(obj); + fd + } + }; + src != -1 && retry(|| dup2(src, dst)) != -1 + }; + + if !setup(in_fd, libc::STDIN_FILENO) { fail(&mut output) } + if !setup(out_fd, libc::STDOUT_FILENO) { fail(&mut output) } + if !setup(err_fd, libc::STDERR_FILENO) { fail(&mut output) } + + // close all other fds + for fd in (3..getdtablesize()).rev() { + if fd != output.fd() { + let _ = close(fd as c_int); + } + } + + match cfg.gid() { + Some(u) => { + if libc::setgid(u as libc::gid_t) != 0 { + fail(&mut output); + } + } + None => {} + } + match cfg.uid() { + Some(u) => { + // When dropping privileges from root, the `setgroups` call + // will remove any extraneous groups. If we don't call this, + // then even though our uid has dropped, we may still have + // groups that enable us to do super-user things. This will + // fail if we aren't root, so don't bother checking the + // return value, this is just done as an optimistic + // privilege dropping function. + extern { + fn setgroups(ngroups: libc::c_int, + ptr: *const libc::c_void) -> libc::c_int; + } + let _ = setgroups(0, ptr::null()); + + if libc::setuid(u as libc::uid_t) != 0 { + fail(&mut output); + } + } + None => {} + } + if cfg.detach() { + // Don't check the error of setsid because it fails if we're the + // process leader already. We just forked so it shouldn't return + // error, but ignore it anyway. + let _ = libc::setsid(); + } + if !dirp.is_null() && chdir(dirp) == -1 { + fail(&mut output); + } + if !envp.is_null() { + *sys::os::environ() = envp as *const _; + } + let _ = execvp(*argv, argv as *mut _); + fail(&mut output); + }) + }) + } pub fn wait(&self, deadline: u64) -> IoResult { use cmp; @@ -556,6 +766,7 @@ fn with_argv(prog: &CString, args: &[CString], cb(ptrs.as_ptr()) } +#[cfg(stage0)] fn with_envp(env: Option<&HashMap>, cb: F) -> T @@ -593,6 +804,44 @@ fn with_envp(env: Option<&HashMap>, _ => cb(ptr::null()) } } +#[cfg(not(stage0))] +fn with_envp(env: Option<&HashMap>, + cb: F) + -> T + where F : FnOnce(*const c_void) -> T, + K : BytesContainer + Eq + Hash, + V : BytesContainer +{ + // On posixy systems we can pass a char** for envp, which is a + // null-terminated array of "k=v\0" strings. Since we must create + // these strings locally, yet expose a raw pointer to them, we + // create a temporary vector to own the CStrings that outlives the + // call to cb. + match env { + Some(env) => { + let mut tmps = Vec::with_capacity(env.len()); + + for pair in env { + let mut kv = Vec::new(); + kv.push_all(pair.0.container_as_bytes()); + kv.push('=' as u8); + kv.push_all(pair.1.container_as_bytes()); + kv.push(0); // terminating null + tmps.push(kv); + } + + // As with `with_argv`, this is unsafe, since cb could leak the pointers. + let mut ptrs: Vec<*const libc::c_char> = + tmps.iter() + .map(|tmp| tmp.as_ptr() as *const libc::c_char) + .collect(); + ptrs.push(ptr::null()); + + cb(ptrs.as_ptr() as *const c_void) + } + _ => cb(ptr::null()) + } +} fn translate_status(status: c_int) -> ProcessExit { #![allow(non_snake_case)] diff --git a/src/libstd/sys/unix/process2.rs b/src/libstd/sys/unix/process2.rs index 5e2c207f3756a..48d11d16f2bc5 100644 --- a/src/libstd/sys/unix/process2.rs +++ b/src/libstd/sys/unix/process2.rs @@ -11,7 +11,6 @@ use prelude::v1::*; use collections::HashMap; -use collections::hash_map::Hasher; use env; use ffi::{OsString, OsStr, CString}; use fmt; diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs index 5aa9f9a0c3e76..2149c7a7f77a7 100644 --- a/src/libsyntax/ext/deriving/hash.rs +++ b/src/libsyntax/ext/deriving/hash.rs @@ -14,7 +14,6 @@ use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::deriving::generic::*; use ext::deriving::generic::ty::*; -use parse::token::InternedString; use ptr::P; pub fn expand_deriving_hash(cx: &mut ExtCtxt, @@ -26,30 +25,26 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt, { let path = Path::new_(pathvec_std!(cx, core::hash::Hash), None, - vec!(box Literal(Path::new_local("__S"))), true); - let generics = LifetimeBounds { - lifetimes: Vec::new(), - bounds: vec!(("__S", - vec!(path_std!(cx, core::hash::Writer), - path_std!(cx, core::hash::Hasher)))), - }; - let args = Path::new_local("__S"); - let inline = cx.meta_word(span, InternedString::new("inline")); - let attrs = vec!(cx.attribute(span, inline)); + vec!(), true); + let arg = Path::new_local("__H"); let hash_trait_def = TraitDef { span: span, attributes: Vec::new(), path: path, additional_bounds: Vec::new(), - generics: generics, + generics: LifetimeBounds::empty(), methods: vec!( MethodDef { name: "hash", - generics: LifetimeBounds::empty(), + generics: LifetimeBounds { + lifetimes: Vec::new(), + bounds: vec![("__H", + vec![path_std!(cx, core::hash::Hasher)])], + }, explicit_self: borrowed_explicit_self(), - args: vec!(Ptr(box Literal(args), Borrowed(None, MutMutable))), + args: vec!(Ptr(box Literal(arg), Borrowed(None, MutMutable))), ret_ty: nil_ty(), - attributes: attrs, + attributes: vec![], combine_substructure: combine_substructure(box |a, b, c| { hash_substructure(a, b, c) }) diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index e8bdcd62b588b..3a7fa54edbdd7 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -28,7 +28,6 @@ #![feature(collections)] #![feature(core)] #![feature(env)] -#![feature(hash)] #![feature(int_uint)] #![feature(old_io)] #![feature(libc)] diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index 01f3839b0390e..adb5383a8fd54 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -111,11 +111,18 @@ impl Display for P { } } +#[cfg(stage0)] impl> Hash for P { fn hash(&self, state: &mut S) { (**self).hash(state); } } +#[cfg(not(stage0))] +impl Hash for P { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } +} impl Decodable for P { fn decode(d: &mut D) -> Result, D::Error> { diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 511442675194e..58b5c44c96075 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -18,9 +18,9 @@ use std::borrow::BorrowFrom; use std::cell::RefCell; use std::cmp::Ordering; use std::collections::HashMap; +#[cfg(stage0)] use std::collections::hash_map::Hasher; use std::fmt; use std::hash::Hash; -use std::collections::hash_map::Hasher; use std::ops::Deref; use std::rc::Rc; @@ -30,6 +30,7 @@ pub struct Interner { } // when traits can extend traits, we should extend index to get [] +#[cfg(stage0)] impl + Clone + 'static> Interner { pub fn new() -> Interner { Interner { @@ -92,6 +93,70 @@ impl + Clone + 'static> Interner { *self.vect.borrow_mut() = Vec::new(); } } +// when traits can extend traits, we should extend index to get [] +#[cfg(not(stage0))] +impl Interner { + pub fn new() -> Interner { + Interner { + map: RefCell::new(HashMap::new()), + vect: RefCell::new(Vec::new()), + } + } + + pub fn prefill(init: &[T]) -> Interner { + let rv = Interner::new(); + for v in init { + rv.intern((*v).clone()); + } + rv + } + + pub fn intern(&self, val: T) -> Name { + let mut map = self.map.borrow_mut(); + match (*map).get(&val) { + Some(&idx) => return idx, + None => (), + } + + let mut vect = self.vect.borrow_mut(); + let new_idx = Name((*vect).len() as u32); + (*map).insert(val.clone(), new_idx); + (*vect).push(val); + new_idx + } + + pub fn gensym(&self, val: T) -> Name { + let mut vect = self.vect.borrow_mut(); + let new_idx = Name((*vect).len() as u32); + // leave out of .map to avoid colliding + (*vect).push(val); + new_idx + } + + pub fn get(&self, idx: Name) -> T { + let vect = self.vect.borrow(); + (*vect)[idx.usize()].clone() + } + + pub fn len(&self) -> usize { + let vect = self.vect.borrow(); + (*vect).len() + } + + pub fn find(&self, val: &Q) -> Option + where Q: BorrowFrom + Eq + Hash { + let map = self.map.borrow(); + match (*map).get(val) { + Some(v) => Some(*v), + None => None, + } + } + + pub fn clear(&self) { + *self.map.borrow_mut() = HashMap::new(); + *self.vect.borrow_mut() = Vec::new(); + } +} #[derive(Clone, PartialEq, Hash, PartialOrd)] pub struct RcStr { @@ -210,6 +275,7 @@ impl StrInterner { self.vect.borrow().len() } + #[cfg(stage0)] pub fn find(&self, val: &Q) -> Option where Q: BorrowFrom + Eq + Hash { match (*self.map.borrow()).get(val) { @@ -217,6 +283,14 @@ impl StrInterner { None => None, } } + #[cfg(not(stage0))] + pub fn find(&self, val: &Q) -> Option + where Q: BorrowFrom + Eq + Hash { + match (*self.map.borrow()).get(val) { + Some(v) => Some(*v), + None => None, + } + } pub fn clear(&self) { *self.map.borrow_mut() = HashMap::new(); diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 2cb30ad9804c6..a03048e39b982 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -37,7 +37,6 @@ #![feature(collections)] #![feature(core)] #![feature(env)] -#![feature(hash)] #![feature(int_uint)] #![feature(old_io)] #![feature(old_path)] diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index 04617757465ec..e7b5820006b34 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -12,7 +12,7 @@ use std::cmp::Ordering::{self, Less, Greater, Equal}; use std::collections::hash_map::Entry::{Occupied, Vacant}; -use std::collections::hash_map::{self, Hasher}; +use std::collections::hash_map; use std::hash::Hash; use std::mem; use std::num::{Float, FromPrimitive}; @@ -333,7 +333,7 @@ pub fn winsorize(samples: &mut [T], pct: T) { /// Returns a HashMap with the number of occurrences of every element in the /// sequence that the iterator exposes. pub fn freq_count(iter: T) -> hash_map::HashMap - where T: Iterator, U: Eq + Clone + Hash + where T: Iterator, U: Eq + Clone + Hash { let mut map: hash_map::HashMap = hash_map::HashMap::new(); for elem in iter { diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index 1d440c4540ca3..7cbc4e1d7af83 100644 --- a/src/test/bench/core-set.rs +++ b/src/test/bench/core-set.rs @@ -18,7 +18,6 @@ extern crate rand; use std::collections::BTreeSet; use std::collections::BitvSet; use std::collections::HashSet; -use std::collections::hash_map::Hasher; use std::hash::Hash; use std::env; use std::time::Duration; @@ -43,7 +42,7 @@ trait MutableSet { fn contains(&self, k: &T) -> bool; } -impl + Eq> MutableSet for HashSet { +impl MutableSet for HashSet { fn insert(&mut self, k: T) { self.insert(k); } fn remove(&mut self, k: &T) -> bool { self.remove(k) } fn contains(&self, k: &T) -> bool { self.contains(k) } diff --git a/src/test/compile-fail/issue-21160.rs b/src/test/compile-fail/issue-21160.rs index 45b7fbbd0b46a..557bf518a3cfb 100644 --- a/src/test/compile-fail/issue-21160.rs +++ b/src/test/compile-fail/issue-21160.rs @@ -16,6 +16,6 @@ impl Bar { #[derive(Hash)] struct Foo(Bar); -//~^ error: the trait `core::hash::Hash<_>` is not implemented for the type `Bar` +//~^ error: the trait `core::hash::Hash` is not implemented for the type `Bar` fn main() {} diff --git a/src/test/run-pass/deriving-hash.rs b/src/test/run-pass/deriving-hash.rs index 02ab7e5db5b89..5fe7c8bb94b4f 100644 --- a/src/test/run-pass/deriving-hash.rs +++ b/src/test/run-pass/deriving-hash.rs @@ -17,7 +17,7 @@ struct Person { phone: uint, } -fn hash>(t: &T) -> u64 { +fn hash(t: &T) -> u64 { std::hash::hash::(t) } diff --git a/src/test/run-pass/deriving-meta-multiple.rs b/src/test/run-pass/deriving-meta-multiple.rs index f45dce9da632e..62ec2f8e5902d 100644 --- a/src/test/run-pass/deriving-meta-multiple.rs +++ b/src/test/run-pass/deriving-meta-multiple.rs @@ -20,7 +20,7 @@ struct Foo { baz: int } -fn hash>(_t: &T) {} +fn hash(_t: &T) {} pub fn main() { let a = Foo {bar: 4, baz: -3}; diff --git a/src/test/run-pass/deriving-meta.rs b/src/test/run-pass/deriving-meta.rs index d6a2fad08ed88..82cf9db3232c0 100644 --- a/src/test/run-pass/deriving-meta.rs +++ b/src/test/run-pass/deriving-meta.rs @@ -17,7 +17,7 @@ struct Foo { baz: int } -fn hash>(_t: &T) {} +fn hash(_t: &T) {} pub fn main() { let a = Foo {bar: 4, baz: -3}; From 5fa9de16df87ab844452821acff1b6c74e948327 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Tue, 17 Feb 2015 23:44:55 -0800 Subject: [PATCH 46/76] Implement RFC 580 This commit implements RFC 580 by renaming: * DList -> LinkedList * Bitv -> BitVec * BitvSet -> BitSet * RingBuf -> VecDeque More details are in [the RFC](https://github.com/rust-lang/rfcs/pull/580) [breaking-change] --- src/libcollections/bit.rs | 1046 +++++++++-------- src/libcollections/btree/map.rs | 12 +- src/libcollections/lib.rs | 44 +- .../{dlist.rs => linked_list.rs} | 234 ++-- src/libcollections/str.rs | 8 +- .../{ring_buf.rs => vec_deque.rs} | 367 +++--- src/librustc/lint/builtin.rs | 4 +- src/librustc/middle/graph.rs | 6 +- src/libserialize/collection_impls.rs | 18 +- src/libstd/collections/mod.rs | 42 +- src/libsyntax/attr.rs | 4 +- src/test/bench/core-set.rs | 8 +- 12 files changed, 917 insertions(+), 876 deletions(-) rename src/libcollections/{dlist.rs => linked_list.rs} (86%) rename src/libcollections/{ring_buf.rs => vec_deque.rs} (90%) diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 0b762788b208a..a2e36155933c9 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -8,13 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// FIXME(Gankro): Bitv and BitvSet are very tightly coupled. Ideally (for -// maintenance), they should be in separate files/modules, with BitvSet only -// using Bitv's public API. This will be hard for performance though, because -// `Bitv` will not want to leak its internal representation while its internal +// FIXME(Gankro): BitVec and BitSet are very tightly coupled. Ideally (for +// maintenance), they should be in separate files/modules, with BitSet only +// using BitVec's public API. This will be hard for performance though, because +// `BitVec` will not want to leak its internal representation while its internal // representation as `u32`s must be assumed for best performance. -// FIXME(tbu-): `Bitv`'s methods shouldn't be `union`, `intersection`, but +// FIXME(tbu-): `BitVec`'s methods shouldn't be `union`, `intersection`, but // rather `or` and `and`. // (1) Be careful, most things can overflow here because the amount of bits in @@ -25,8 +25,8 @@ // methods rely on it (for *CORRECTNESS*). // (3) Make sure that the unused bits in the last word are zeroed out, again // other methods rely on it for *CORRECTNESS*. -// (4) `BitvSet` is tightly coupled with `Bitv`, so any changes you make in -// `Bitv` will need to be reflected in `BitvSet`. +// (4) `BitSet` is tightly coupled with `BitVec`, so any changes you make in +// `BitVec` will need to be reflected in `BitSet`. //! Collections implemented with bit vectors. //! @@ -38,17 +38,17 @@ //! [sieve]: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes //! //! ``` -//! use std::collections::{BitvSet, Bitv}; +//! use std::collections::{BitSet, BitVec}; //! use std::num::Float; //! use std::iter; //! //! let max_prime = 10000; //! -//! // Store the primes as a BitvSet +//! // Store the primes as a BitSet //! let primes = { //! // Assume all numbers are prime to begin, and then we //! // cross off non-primes progressively -//! let mut bv = Bitv::from_elem(max_prime, true); +//! let mut bv = BitVec::from_elem(max_prime, true); //! //! // Neither 0 nor 1 are prime //! bv.set(0, false); @@ -62,7 +62,7 @@ //! for j in iter::range_step(i * i, max_prime, i) { bv.set(j, false) } //! } //! } -//! BitvSet::from_bitv(bv) +//! BitSet::from_bit_vec(bv) //! }; //! //! // Simple primality tests below our max bound @@ -75,7 +75,7 @@ //! } //! println!(""); //! -//! // We can manipulate the internal Bitv +//! // We can manipulate the internal BitVec //! let num_primes = primes.get_ref().iter().filter(|x| *x).count(); //! println!("There are {} primes below {}", num_primes, max_prime); //! ``` @@ -94,7 +94,7 @@ use core::num::Int; use core::ops::Index; use core::slice; use core::{u8, u32, usize}; -use bitv_set; //so meta +use bit_set; //so meta use Vec; @@ -112,7 +112,7 @@ fn reverse_bits(byte: u8) -> u8 { // Take two BitV's, and return iterators of their words, where the shorter one // has been padded with 0's -fn match_words <'a,'b>(a: &'a Bitv, b: &'b Bitv) -> (MatchWords<'a>, MatchWords<'b>) { +fn match_words <'a,'b>(a: &'a BitVec, b: &'b BitVec) -> (MatchWords<'a>, MatchWords<'b>) { let a_len = a.storage.len(); let b_len = b.storage.len(); @@ -134,9 +134,9 @@ static FALSE: bool = false; /// # Examples /// /// ```rust -/// use std::collections::Bitv; +/// use std::collections::BitVec; /// -/// let mut bv = Bitv::from_elem(10, false); +/// let mut bv = BitVec::from_elem(10, false); /// /// // insert all primes less than 10 /// bv.set(2, true); @@ -158,7 +158,7 @@ static FALSE: bool = false; /// ``` #[unstable(feature = "collections", reason = "RFC 509")] -pub struct Bitv { +pub struct BitVec { /// Internal representation of the bit vector storage: Vec, /// The number of valid bits in the internal representation @@ -166,7 +166,7 @@ pub struct Bitv { } // FIXME(Gankro): NopeNopeNopeNopeNope (wait for IndexGet to be a thing) -impl Index for Bitv { +impl Index for BitVec { type Output = bool; #[inline] @@ -202,12 +202,12 @@ fn mask_for_bits(bits: usize) -> u32 { !0u32 >> (u32::BITS - bits % u32::BITS) % u32::BITS } -impl Bitv { +impl BitVec { /// Applies the given operation to the blocks of self and other, and sets /// self to be the result. This relies on the caller not to corrupt the /// last word. #[inline] - fn process(&mut self, other: &Bitv, mut op: F) -> bool where F: FnMut(u32, u32) -> u32 { + fn process(&mut self, other: &BitVec, mut op: F) -> bool where F: FnMut(u32, u32) -> u32 { assert_eq!(self.len(), other.len()); // This could theoretically be a `debug_assert!`. assert_eq!(self.storage.len(), other.storage.len()); @@ -235,7 +235,7 @@ impl Bitv { } /// An operation might screw up the unused bits in the last block of the - /// `Bitv`. As per (3), it's assumed to be all 0s. This method fixes it up. + /// `BitVec`. As per (3), it's assumed to be all 0s. This method fixes it up. fn fix_last_block(&mut self) { let extra_bits = self.len() % u32::BITS; if extra_bits > 0 { @@ -245,44 +245,44 @@ impl Bitv { } } - /// Creates an empty `Bitv`. + /// Creates an empty `BitVec`. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; - /// let mut bv = Bitv::new(); + /// use std::collections::BitVec; + /// let mut bv = BitVec::new(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> Bitv { - Bitv { storage: Vec::new(), nbits: 0 } + pub fn new() -> BitVec { + BitVec { storage: Vec::new(), nbits: 0 } } - /// Creates a `Bitv` that holds `nbits` elements, setting each element + /// Creates a `BitVec` that holds `nbits` elements, setting each element /// to `bit`. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(10, false); + /// let mut bv = BitVec::from_elem(10, false); /// assert_eq!(bv.len(), 10); /// for x in bv.iter() { /// assert_eq!(x, false); /// } /// ``` - pub fn from_elem(nbits: usize, bit: bool) -> Bitv { + pub fn from_elem(nbits: usize, bit: bool) -> BitVec { let nblocks = blocks_for_bits(nbits); - let mut bitv = Bitv { + let mut bit_vec = BitVec { storage: repeat(if bit { !0u32 } else { 0u32 }).take(nblocks).collect(), nbits: nbits }; - bitv.fix_last_block(); - bitv + bit_vec.fix_last_block(); + bit_vec } - /// Constructs a new, empty `Bitv` with the specified capacity. + /// Constructs a new, empty `BitVec` with the specified capacity. /// /// The bitvector will be able to hold at least `capacity` bits without /// reallocating. If `capacity` is 0, it will not allocate. @@ -290,38 +290,38 @@ impl Bitv { /// It is important to note that this function does not specify the /// *length* of the returned bitvector, but only the *capacity*. #[stable(feature = "rust1", since = "1.0.0")] - pub fn with_capacity(nbits: usize) -> Bitv { - Bitv { + pub fn with_capacity(nbits: usize) -> BitVec { + BitVec { storage: Vec::with_capacity(blocks_for_bits(nbits)), nbits: 0, } } - /// Transforms a byte-vector into a `Bitv`. Each byte becomes eight bits, + /// Transforms a byte-vector into a `BitVec`. Each byte becomes eight bits, /// with the most significant bits of each byte coming first. Each /// bit becomes `true` if equal to 1 or `false` if equal to 0. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let bv = Bitv::from_bytes(&[0b10100000, 0b00010010]); + /// let bv = BitVec::from_bytes(&[0b10100000, 0b00010010]); /// assert!(bv.eq_vec(&[true, false, true, false, /// false, false, false, false, /// false, false, false, true, /// false, false, true, false])); /// ``` - pub fn from_bytes(bytes: &[u8]) -> Bitv { + pub fn from_bytes(bytes: &[u8]) -> BitVec { let len = bytes.len().checked_mul(u8::BITS).expect("capacity overflow"); - let mut bitv = Bitv::with_capacity(len); + let mut bit_vec = BitVec::with_capacity(len); let complete_words = bytes.len() / 4; let extra_bytes = bytes.len() % 4; - bitv.nbits = len; + bit_vec.nbits = len; for i in 0..complete_words { - bitv.storage.push( + bit_vec.storage.push( ((reverse_bits(bytes[i * 4 + 0]) as u32) << 0) | ((reverse_bits(bytes[i * 4 + 1]) as u32) << 8) | ((reverse_bits(bytes[i * 4 + 2]) as u32) << 16) | @@ -334,29 +334,29 @@ impl Bitv { for (i, &byte) in bytes[complete_words*4..].iter().enumerate() { last_word |= (reverse_bits(byte) as u32) << (i * 8); } - bitv.storage.push(last_word); + bit_vec.storage.push(last_word); } - bitv + bit_vec } - /// Creates a `Bitv` of the specified length where the value at each index + /// Creates a `BitVec` of the specified length where the value at each index /// is `f(index)`. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let bv = Bitv::from_fn(5, |i| { i % 2 == 0 }); + /// let bv = BitVec::from_fn(5, |i| { i % 2 == 0 }); /// assert!(bv.eq_vec(&[true, false, true, false, true])); /// ``` - pub fn from_fn(len: usize, mut f: F) -> Bitv where F: FnMut(usize) -> bool { - let mut bitv = Bitv::from_elem(len, false); + pub fn from_fn(len: usize, mut f: F) -> BitVec where F: FnMut(usize) -> bool { + let mut bit_vec = BitVec::from_elem(len, false); for i in 0..len { - bitv.set(i, f(i)); + bit_vec.set(i, f(i)); } - bitv + bit_vec } /// Retrieves the value at index `i`, or `None` if the index is out of bounds. @@ -364,9 +364,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let bv = Bitv::from_bytes(&[0b01100000]); + /// let bv = BitVec::from_bytes(&[0b01100000]); /// assert_eq!(bv.get(0), Some(false)); /// assert_eq!(bv.get(1), Some(true)); /// assert_eq!(bv.get(100), None); @@ -396,9 +396,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(5, false); + /// let mut bv = BitVec::from_elem(5, false); /// bv.set(3, true); /// assert_eq!(bv[3], true); /// ``` @@ -420,14 +420,14 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// /// let before = 0b01100000; /// let after = 0b11111111; /// - /// let mut bv = Bitv::from_bytes(&[before]); + /// let mut bv = BitVec::from_bytes(&[before]); /// bv.set_all(); - /// assert_eq!(bv, Bitv::from_bytes(&[after])); + /// assert_eq!(bv, BitVec::from_bytes(&[after])); /// ``` #[inline] pub fn set_all(&mut self) { @@ -440,14 +440,14 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// /// let before = 0b01100000; /// let after = 0b10011111; /// - /// let mut bv = Bitv::from_bytes(&[before]); + /// let mut bv = BitVec::from_bytes(&[before]); /// bv.negate(); - /// assert_eq!(bv, Bitv::from_bytes(&[after])); + /// assert_eq!(bv, BitVec::from_bytes(&[after])); /// ``` #[inline] pub fn negate(&mut self) { @@ -468,20 +468,20 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// /// let a = 0b01100100; /// let b = 0b01011010; /// let res = 0b01111110; /// - /// let mut a = Bitv::from_bytes(&[a]); - /// let b = Bitv::from_bytes(&[b]); + /// let mut a = BitVec::from_bytes(&[a]); + /// let b = BitVec::from_bytes(&[b]); /// /// assert!(a.union(&b)); - /// assert_eq!(a, Bitv::from_bytes(&[res])); + /// assert_eq!(a, BitVec::from_bytes(&[res])); /// ``` #[inline] - pub fn union(&mut self, other: &Bitv) -> bool { + pub fn union(&mut self, other: &BitVec) -> bool { self.process(other, |w1, w2| w1 | w2) } @@ -498,20 +498,20 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// /// let a = 0b01100100; /// let b = 0b01011010; /// let res = 0b01000000; /// - /// let mut a = Bitv::from_bytes(&[a]); - /// let b = Bitv::from_bytes(&[b]); + /// let mut a = BitVec::from_bytes(&[a]); + /// let b = BitVec::from_bytes(&[b]); /// /// assert!(a.intersect(&b)); - /// assert_eq!(a, Bitv::from_bytes(&[res])); + /// assert_eq!(a, BitVec::from_bytes(&[res])); /// ``` #[inline] - pub fn intersect(&mut self, other: &Bitv) -> bool { + pub fn intersect(&mut self, other: &BitVec) -> bool { self.process(other, |w1, w2| w1 & w2) } @@ -528,27 +528,27 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// /// let a = 0b01100100; /// let b = 0b01011010; /// let a_b = 0b00100100; // a - b /// let b_a = 0b00011010; // b - a /// - /// let mut bva = Bitv::from_bytes(&[a]); - /// let bvb = Bitv::from_bytes(&[b]); + /// let mut bva = BitVec::from_bytes(&[a]); + /// let bvb = BitVec::from_bytes(&[b]); /// /// assert!(bva.difference(&bvb)); - /// assert_eq!(bva, Bitv::from_bytes(&[a_b])); + /// assert_eq!(bva, BitVec::from_bytes(&[a_b])); /// - /// let bva = Bitv::from_bytes(&[a]); - /// let mut bvb = Bitv::from_bytes(&[b]); + /// let bva = BitVec::from_bytes(&[a]); + /// let mut bvb = BitVec::from_bytes(&[b]); /// /// assert!(bvb.difference(&bva)); - /// assert_eq!(bvb, Bitv::from_bytes(&[b_a])); + /// assert_eq!(bvb, BitVec::from_bytes(&[b_a])); /// ``` #[inline] - pub fn difference(&mut self, other: &Bitv) -> bool { + pub fn difference(&mut self, other: &BitVec) -> bool { self.process(other, |w1, w2| w1 & !w2) } @@ -557,9 +557,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(5, true); + /// let mut bv = BitVec::from_elem(5, true); /// assert_eq!(bv.all(), true); /// /// bv.set(1, false); @@ -581,15 +581,15 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let bv = Bitv::from_bytes(&[0b01110100, 0b10010010]); + /// let bv = BitVec::from_bytes(&[0b01110100, 0b10010010]); /// assert_eq!(bv.iter().filter(|x| *x).count(), 7); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn iter(&self) -> Iter { - Iter { bitv: self, next_idx: 0, end_idx: self.nbits } + Iter { bit_vec: self, next_idx: 0, end_idx: self.nbits } } /// Returns `true` if all bits are 0. @@ -597,9 +597,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(10, false); + /// let mut bv = BitVec::from_elem(10, false); /// assert_eq!(bv.none(), true); /// /// bv.set(3, true); @@ -614,9 +614,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(10, false); + /// let mut bv = BitVec::from_elem(10, false); /// assert_eq!(bv.any(), false); /// /// bv.set(3, true); @@ -628,33 +628,33 @@ impl Bitv { } /// Organises the bits into bytes, such that the first bit in the - /// `Bitv` becomes the high-order bit of the first byte. If the - /// size of the `Bitv` is not a multiple of eight then trailing bits + /// `BitVec` becomes the high-order bit of the first byte. If the + /// size of the `BitVec` is not a multiple of eight then trailing bits /// will be filled-in with `false`. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(3, true); + /// let mut bv = BitVec::from_elem(3, true); /// bv.set(1, false); /// /// assert_eq!(bv.to_bytes(), vec!(0b10100000)); /// - /// let mut bv = Bitv::from_elem(9, false); + /// let mut bv = BitVec::from_elem(9, false); /// bv.set(2, true); /// bv.set(8, true); /// /// assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000)); /// ``` pub fn to_bytes(&self) -> Vec { - fn bit(bitv: &Bitv, byte: usize, bit: usize) -> u8 { + fn bit(bit_vec: &BitVec, byte: usize, bit: usize) -> u8 { let offset = byte * 8 + bit; - if offset >= bitv.nbits { + if offset >= bit_vec.nbits { 0 } else { - (bitv[offset] as u8) << (7 - bit) + (bit_vec[offset] as u8) << (7 - bit) } } @@ -672,19 +672,19 @@ impl Bitv { ).collect() } - /// Compares a `Bitv` to a slice of `bool`s. - /// Both the `Bitv` and slice must have the same length. + /// Compares a `BitVec` to a slice of `bool`s. + /// Both the `BitVec` and slice must have the same length. /// /// # Panics /// - /// Panics if the `Bitv` and slice are of different length. + /// Panics if the `BitVec` and slice are of different length. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let bv = Bitv::from_bytes(&[0b10100000]); + /// let bv = BitVec::from_bytes(&[0b10100000]); /// /// assert!(bv.eq_vec(&[true, false, true, false, /// false, false, false, false])); @@ -694,7 +694,7 @@ impl Bitv { iter::order::eq(self.iter(), v.iter().cloned()) } - /// Shortens a `Bitv`, dropping excess elements. + /// Shortens a `BitVec`, dropping excess elements. /// /// If `len` is greater than the vector's current length, this has no /// effect. @@ -702,9 +702,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_bytes(&[0b01001011]); + /// let mut bv = BitVec::from_bytes(&[0b01001011]); /// bv.truncate(2); /// assert!(bv.eq_vec(&[false, true])); /// ``` @@ -719,7 +719,7 @@ impl Bitv { } /// Reserves capacity for at least `additional` more bits to be inserted in the given - /// `Bitv`. The collection may reserve more space to avoid frequent reallocations. + /// `BitVec`. The collection may reserve more space to avoid frequent reallocations. /// /// # Panics /// @@ -728,9 +728,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(3, false); + /// let mut bv = BitVec::from_elem(3, false); /// bv.reserve(10); /// assert_eq!(bv.len(), 3); /// assert!(bv.capacity() >= 13); @@ -745,7 +745,7 @@ impl Bitv { } /// Reserves the minimum capacity for exactly `additional` more bits to be inserted in the - /// given `Bitv`. Does nothing if the capacity is already sufficient. + /// given `BitVec`. Does nothing if the capacity is already sufficient. /// /// Note that the allocator may give the collection more space than it requests. Therefore /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future @@ -758,9 +758,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_elem(3, false); + /// let mut bv = BitVec::from_elem(3, false); /// bv.reserve(10); /// assert_eq!(bv.len(), 3); /// assert!(bv.capacity() >= 13); @@ -780,9 +780,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::new(); + /// let mut bv = BitVec::new(); /// bv.reserve(10); /// assert!(bv.capacity() >= 10); /// ``` @@ -792,7 +792,7 @@ impl Bitv { self.storage.capacity().checked_mul(u32::BITS).unwrap_or(usize::MAX) } - /// Grows the `Bitv` in-place, adding `n` copies of `value` to the `Bitv`. + /// Grows the `BitVec` in-place, adding `n` copies of `value` to the `BitVec`. /// /// # Panics /// @@ -801,9 +801,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_bytes(&[0b01001011]); + /// let mut bv = BitVec::from_bytes(&[0b01001011]); /// bv.grow(2, true); /// assert_eq!(bv.len(), 10); /// assert_eq!(bv.to_bytes(), vec!(0b01001011, 0b11000000)); @@ -846,14 +846,14 @@ impl Bitv { self.fix_last_block(); } - /// Removes the last bit from the Bitv, and returns it. Returns None if the Bitv is empty. + /// Removes the last bit from the BitVec, and returns it. Returns None if the BitVec is empty. /// /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::from_bytes(&[0b01001001]); + /// let mut bv = BitVec::from_bytes(&[0b01001001]); /// assert_eq!(bv.pop(), Some(true)); /// assert_eq!(bv.pop(), Some(false)); /// assert_eq!(bv.len(), 6); @@ -881,9 +881,9 @@ impl Bitv { /// # Examples /// /// ``` - /// use std::collections::Bitv; + /// use std::collections::BitVec; /// - /// let mut bv = Bitv::new(); + /// let mut bv = BitVec::new(); /// bv.push(true); /// bv.push(false); /// assert!(bv.eq_vec(&[true, false])); @@ -917,22 +917,22 @@ impl Bitv { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for Bitv { +impl Default for BitVec { #[inline] - fn default() -> Bitv { Bitv::new() } + fn default() -> BitVec { BitVec::new() } } #[stable(feature = "rust1", since = "1.0.0")] -impl FromIterator for Bitv { - fn from_iter>(iterator: I) -> Bitv { - let mut ret = Bitv::new(); +impl FromIterator for BitVec { + fn from_iter>(iterator: I) -> BitVec { + let mut ret = BitVec::new(); ret.extend(iterator); ret } } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for Bitv { +impl Extend for BitVec { #[inline] fn extend>(&mut self, iterator: I) { let (min, _) = iterator.size_hint(); @@ -944,37 +944,37 @@ impl Extend for Bitv { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Bitv { +impl Clone for BitVec { #[inline] - fn clone(&self) -> Bitv { - Bitv { storage: self.storage.clone(), nbits: self.nbits } + fn clone(&self) -> BitVec { + BitVec { storage: self.storage.clone(), nbits: self.nbits } } #[inline] - fn clone_from(&mut self, source: &Bitv) { + fn clone_from(&mut self, source: &BitVec) { self.nbits = source.nbits; self.storage.clone_from(&source.storage); } } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for Bitv { +impl PartialOrd for BitVec { #[inline] - fn partial_cmp(&self, other: &Bitv) -> Option { + fn partial_cmp(&self, other: &BitVec) -> Option { iter::order::partial_cmp(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for Bitv { +impl Ord for BitVec { #[inline] - fn cmp(&self, other: &Bitv) -> Ordering { + fn cmp(&self, other: &BitVec) -> Ordering { iter::order::cmp(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for Bitv { +impl fmt::Debug for BitVec { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { for bit in self { try!(write!(fmt, "{}", if bit { 1u32 } else { 0u32 })); @@ -984,7 +984,7 @@ impl fmt::Debug for Bitv { } #[stable(feature = "rust1", since = "1.0.0")] -impl hash::Hash for Bitv { +impl hash::Hash for BitVec { fn hash(&self, state: &mut S) { self.nbits.hash(state); for elem in self.blocks() { @@ -994,9 +994,9 @@ impl hash::Hash for Bitv { } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::PartialEq for Bitv { +impl cmp::PartialEq for BitVec { #[inline] - fn eq(&self, other: &Bitv) -> bool { + fn eq(&self, other: &BitVec) -> bool { if self.nbits != other.nbits { return false; } @@ -1005,13 +1005,13 @@ impl cmp::PartialEq for Bitv { } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::Eq for Bitv {} +impl cmp::Eq for BitVec {} -/// An iterator for `Bitv`. +/// An iterator for `BitVec`. #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Iter<'a> { - bitv: &'a Bitv, + bit_vec: &'a BitVec, next_idx: usize, end_idx: usize, } @@ -1025,7 +1025,7 @@ impl<'a> Iterator for Iter<'a> { if self.next_idx != self.end_idx { let idx = self.next_idx; self.next_idx += 1; - Some(self.bitv[idx]) + Some(self.bit_vec[idx]) } else { None } @@ -1043,7 +1043,7 @@ impl<'a> DoubleEndedIterator for Iter<'a> { fn next_back(&mut self) -> Option { if self.next_idx != self.end_idx { self.end_idx -= 1; - Some(self.bitv[self.end_idx]) + Some(self.bit_vec[self.end_idx]) } else { None } @@ -1065,13 +1065,13 @@ impl<'a> RandomAccessIterator for Iter<'a> { if index >= self.indexable() { None } else { - Some(self.bitv[index]) + Some(self.bit_vec[index]) } } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a> IntoIterator for &'a Bitv { +impl<'a> IntoIterator for &'a BitVec { type Item = bool; type IntoIter = Iter<'a>; @@ -1090,10 +1090,10 @@ impl<'a> IntoIterator for &'a Bitv { /// # Examples /// /// ``` -/// use std::collections::{BitvSet, Bitv}; +/// use std::collections::{BitSet, BitVec}; /// /// // It's a regular set -/// let mut s = BitvSet::new(); +/// let mut s = BitSet::new(); /// s.insert(0); /// s.insert(3); /// s.insert(7); @@ -1104,8 +1104,8 @@ impl<'a> IntoIterator for &'a Bitv { /// println!("There is no 7"); /// } /// -/// // Can initialize from a `Bitv` -/// let other = BitvSet::from_bitv(Bitv::from_bytes(&[0b11010000])); +/// // Can initialize from a `BitVec` +/// let other = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11010000])); /// /// s.union_with(&other); /// @@ -1114,34 +1114,34 @@ impl<'a> IntoIterator for &'a Bitv { /// println!("{}", x); /// } /// -/// // Can convert back to a `Bitv` -/// let bv: Bitv = s.into_bitv(); +/// // Can convert back to a `BitVec` +/// let bv: BitVec = s.into_bit_vec(); /// assert!(bv[3]); /// ``` #[derive(Clone)] #[unstable(feature = "collections", reason = "RFC 509")] -pub struct BitvSet { - bitv: Bitv, +pub struct BitSet { + bit_vec: BitVec, } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for BitvSet { +impl Default for BitSet { #[inline] - fn default() -> BitvSet { BitvSet::new() } + fn default() -> BitSet { BitSet::new() } } #[stable(feature = "rust1", since = "1.0.0")] -impl FromIterator for BitvSet { - fn from_iter>(iterator: I) -> BitvSet { - let mut ret = BitvSet::new(); +impl FromIterator for BitSet { + fn from_iter>(iterator: I) -> BitSet { + let mut ret = BitSet::new(); ret.extend(iterator); ret } } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for BitvSet { +impl Extend for BitSet { #[inline] fn extend>(&mut self, iterator: I) { for i in iterator { @@ -1151,78 +1151,78 @@ impl Extend for BitvSet { } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for BitvSet { +impl PartialOrd for BitSet { #[inline] - fn partial_cmp(&self, other: &BitvSet) -> Option { + fn partial_cmp(&self, other: &BitSet) -> Option { let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref()); iter::order::partial_cmp(a_iter, b_iter) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for BitvSet { +impl Ord for BitSet { #[inline] - fn cmp(&self, other: &BitvSet) -> Ordering { + fn cmp(&self, other: &BitSet) -> Ordering { let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref()); iter::order::cmp(a_iter, b_iter) } } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::PartialEq for BitvSet { +impl cmp::PartialEq for BitSet { #[inline] - fn eq(&self, other: &BitvSet) -> bool { + fn eq(&self, other: &BitSet) -> bool { let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref()); iter::order::eq(a_iter, b_iter) } } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::Eq for BitvSet {} +impl cmp::Eq for BitSet {} -impl BitvSet { - /// Creates a new empty `BitvSet`. +impl BitSet { + /// Creates a new empty `BitSet`. /// /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::new(); + /// let mut s = BitSet::new(); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> BitvSet { - BitvSet { bitv: Bitv::new() } + pub fn new() -> BitSet { + BitSet { bit_vec: BitVec::new() } } - /// Creates a new `BitvSet` with initially no contents, able to + /// Creates a new `BitSet` with initially no contents, able to /// hold `nbits` elements without resizing. /// /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::with_capacity(100); + /// let mut s = BitSet::with_capacity(100); /// assert!(s.capacity() >= 100); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn with_capacity(nbits: usize) -> BitvSet { - let bitv = Bitv::from_elem(nbits, false); - BitvSet::from_bitv(bitv) + pub fn with_capacity(nbits: usize) -> BitSet { + let bit_vec = BitVec::from_elem(nbits, false); + BitSet::from_bit_vec(bit_vec) } - /// Creates a new `BitvSet` from the given bit vector. + /// Creates a new `BitSet` from the given bit vector. /// /// # Examples /// /// ``` - /// use std::collections::{Bitv, BitvSet}; + /// use std::collections::{BitVec, BitSet}; /// - /// let bv = Bitv::from_bytes(&[0b01100000]); - /// let s = BitvSet::from_bitv(bv); + /// let bv = BitVec::from_bytes(&[0b01100000]); + /// let s = BitSet::from_bit_vec(bv); /// /// // Print 1, 2 in arbitrary order /// for x in s.iter() { @@ -1230,8 +1230,16 @@ impl BitvSet { /// } /// ``` #[inline] - pub fn from_bitv(bitv: Bitv) -> BitvSet { - BitvSet { bitv: bitv } + pub fn from_bit_vec(bit_vec: BitVec) -> BitSet { + BitSet { bit_vec: bit_vec } + } + + /// Deprecated: use `from_bit_vec`. + #[inline] + #[deprecated(since = "1.0.0", reason = "renamed to from_bit_vec")] + #[unstable(feature = "collections")] + pub fn from_bitv(bit_vec: BitVec) -> BitSet { + BitSet { bit_vec: bit_vec } } /// Returns the capacity in bits for this bit vector. Inserting any @@ -1240,19 +1248,19 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::with_capacity(100); + /// let mut s = BitSet::with_capacity(100); /// assert!(s.capacity() >= 100); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn capacity(&self) -> usize { - self.bitv.capacity() + self.bit_vec.capacity() } - /// Reserves capacity for the given `BitvSet` to contain `len` distinct elements. In the case - /// of `BitvSet` this means reallocations will not occur as long as all inserted elements + /// Reserves capacity for the given `BitSet` to contain `len` distinct elements. In the case + /// of `BitSet` this means reallocations will not occur as long as all inserted elements /// are less than `len`. /// /// The collection may reserve more space to avoid frequent reallocations. @@ -1261,22 +1269,22 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::new(); + /// let mut s = BitSet::new(); /// s.reserve_len(10); /// assert!(s.capacity() >= 10); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn reserve_len(&mut self, len: usize) { - let cur_len = self.bitv.len(); + let cur_len = self.bit_vec.len(); if len >= cur_len { - self.bitv.reserve(len - cur_len); + self.bit_vec.reserve(len - cur_len); } } - /// Reserves the minimum capacity for the given `BitvSet` to contain `len` distinct elements. - /// In the case of `BitvSet` this means reallocations will not occur as long as all inserted + /// Reserves the minimum capacity for the given `BitSet` to contain `len` distinct elements. + /// In the case of `BitSet` this means reallocations will not occur as long as all inserted /// elements are less than `len`. /// /// Note that the allocator may give the collection more space than it requests. Therefore @@ -1287,17 +1295,17 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::new(); + /// let mut s = BitSet::new(); /// s.reserve_len_exact(10); /// assert!(s.capacity() >= 10); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn reserve_len_exact(&mut self, len: usize) { - let cur_len = self.bitv.len(); + let cur_len = self.bit_vec.len(); if len >= cur_len { - self.bitv.reserve_exact(len - cur_len); + self.bit_vec.reserve_exact(len - cur_len); } } @@ -1307,19 +1315,19 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::new(); + /// let mut s = BitSet::new(); /// s.insert(0); /// s.insert(3); /// - /// let bv = s.into_bitv(); + /// let bv = s.into_bit_vec(); /// assert!(bv[0]); /// assert!(bv[3]); /// ``` #[inline] - pub fn into_bitv(self) -> Bitv { - self.bitv + pub fn into_bit_vec(self) -> BitVec { + self.bit_vec } /// Returns a reference to the underlying bit vector. @@ -1327,44 +1335,44 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::new(); + /// let mut s = BitSet::new(); /// s.insert(0); /// /// let bv = s.get_ref(); /// assert_eq!(bv[0], true); /// ``` #[inline] - pub fn get_ref(&self) -> &Bitv { - &self.bitv + pub fn get_ref(&self) -> &BitVec { + &self.bit_vec } #[inline] - fn other_op(&mut self, other: &BitvSet, mut f: F) where F: FnMut(u32, u32) -> u32 { - // Unwrap Bitvs - let self_bitv = &mut self.bitv; - let other_bitv = &other.bitv; + fn other_op(&mut self, other: &BitSet, mut f: F) where F: FnMut(u32, u32) -> u32 { + // Unwrap BitVecs + let self_bit_vec = &mut self.bit_vec; + let other_bit_vec = &other.bit_vec; - let self_len = self_bitv.len(); - let other_len = other_bitv.len(); + let self_len = self_bit_vec.len(); + let other_len = other_bit_vec.len(); // Expand the vector if necessary if self_len < other_len { - self_bitv.grow(other_len - self_len, false); + self_bit_vec.grow(other_len - self_len, false); } // virtually pad other with 0's for equal lengths let other_words = { - let (_, result) = match_words(self_bitv, other_bitv); + let (_, result) = match_words(self_bit_vec, other_bit_vec); result }; // Apply values found in other for (i, w) in other_words { - let old = self_bitv.storage[i]; + let old = self_bit_vec.storage[i]; let new = f(old, w); - self_bitv.storage[i] = new; + self_bit_vec.storage[i] = new; } } @@ -1373,9 +1381,9 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::BitvSet; + /// use std::collections::BitSet; /// - /// let mut s = BitvSet::new(); + /// let mut s = BitSet::new(); /// s.insert(32183231); /// s.remove(&32183231); /// @@ -1389,25 +1397,25 @@ impl BitvSet { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn shrink_to_fit(&mut self) { - let bitv = &mut self.bitv; + let bit_vec = &mut self.bit_vec; // Obtain original length - let old_len = bitv.storage.len(); + let old_len = bit_vec.storage.len(); // Obtain coarse trailing zero length - let n = bitv.storage.iter().rev().take_while(|&&n| n == 0).count(); + let n = bit_vec.storage.iter().rev().take_while(|&&n| n == 0).count(); // Truncate let trunc_len = cmp::max(old_len - n, 1); - bitv.storage.truncate(trunc_len); - bitv.nbits = trunc_len * u32::BITS; + bit_vec.storage.truncate(trunc_len); + bit_vec.nbits = trunc_len * u32::BITS; } - /// Iterator over each u32 stored in the `BitvSet`. + /// Iterator over each u32 stored in the `BitSet`. /// /// # Examples /// /// ``` - /// use std::collections::{Bitv, BitvSet}; + /// use std::collections::{BitVec, BitSet}; /// - /// let s = BitvSet::from_bitv(Bitv::from_bytes(&[0b01001010])); + /// let s = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01001010])); /// /// // Print 1, 4, 6 in arbitrary order /// for x in s.iter() { @@ -1416,7 +1424,7 @@ impl BitvSet { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn iter(&self) -> bitv_set::Iter { + pub fn iter(&self) -> bit_set::Iter { SetIter {set: self, next_idx: 0} } @@ -1426,10 +1434,10 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{Bitv, BitvSet}; + /// use std::collections::{BitVec, BitSet}; /// - /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000])); + /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000])); /// /// // Print 0, 1, 2, 4 in arbitrary order /// for x in a.union(&b) { @@ -1438,7 +1446,7 @@ impl BitvSet { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn union<'a>(&'a self, other: &'a BitvSet) -> Union<'a> { + pub fn union<'a>(&'a self, other: &'a BitSet) -> Union<'a> { fn or(w1: u32, w2: u32) -> u32 { w1 | w2 } Union(TwoBitPositions { @@ -1456,10 +1464,10 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{Bitv, BitvSet}; + /// use std::collections::{BitVec, BitSet}; /// - /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000])); + /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000])); /// /// // Print 2 /// for x in a.intersection(&b) { @@ -1468,9 +1476,9 @@ impl BitvSet { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Intersection<'a> { + pub fn intersection<'a>(&'a self, other: &'a BitSet) -> Intersection<'a> { fn bitand(w1: u32, w2: u32) -> u32 { w1 & w2 } - let min = cmp::min(self.bitv.len(), other.bitv.len()); + let min = cmp::min(self.bit_vec.len(), other.bit_vec.len()); Intersection(TwoBitPositions { set: self, other: other, @@ -1486,10 +1494,10 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{BitvSet, Bitv}; + /// use std::collections::{BitSet, BitVec}; /// - /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000])); + /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000])); /// /// // Print 1, 4 in arbitrary order /// for x in a.difference(&b) { @@ -1505,7 +1513,7 @@ impl BitvSet { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn difference<'a>(&'a self, other: &'a BitvSet) -> Difference<'a> { + pub fn difference<'a>(&'a self, other: &'a BitSet) -> Difference<'a> { fn diff(w1: u32, w2: u32) -> u32 { w1 & !w2 } Difference(TwoBitPositions { @@ -1524,10 +1532,10 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{BitvSet, Bitv}; + /// use std::collections::{BitSet, BitVec}; /// - /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000])); + /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000])); /// /// // Print 0, 1, 4 in arbitrary order /// for x in a.symmetric_difference(&b) { @@ -1536,7 +1544,7 @@ impl BitvSet { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> SymmetricDifference<'a> { + pub fn symmetric_difference<'a>(&'a self, other: &'a BitSet) -> SymmetricDifference<'a> { fn bitxor(w1: u32, w2: u32) -> u32 { w1 ^ w2 } SymmetricDifference(TwoBitPositions { @@ -1553,21 +1561,21 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{BitvSet, Bitv}; + /// use std::collections::{BitSet, BitVec}; /// /// let a = 0b01101000; /// let b = 0b10100000; /// let res = 0b11101000; /// - /// let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[a])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[b])); - /// let res = BitvSet::from_bitv(Bitv::from_bytes(&[res])); + /// let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[a])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[b])); + /// let res = BitSet::from_bit_vec(BitVec::from_bytes(&[res])); /// /// a.union_with(&b); /// assert_eq!(a, res); /// ``` #[inline] - pub fn union_with(&mut self, other: &BitvSet) { + pub fn union_with(&mut self, other: &BitSet) { self.other_op(other, |w1, w2| w1 | w2); } @@ -1576,21 +1584,21 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{BitvSet, Bitv}; + /// use std::collections::{BitSet, BitVec}; /// /// let a = 0b01101000; /// let b = 0b10100000; /// let res = 0b00100000; /// - /// let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[a])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[b])); - /// let res = BitvSet::from_bitv(Bitv::from_bytes(&[res])); + /// let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[a])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[b])); + /// let res = BitSet::from_bit_vec(BitVec::from_bytes(&[res])); /// /// a.intersect_with(&b); /// assert_eq!(a, res); /// ``` #[inline] - pub fn intersect_with(&mut self, other: &BitvSet) { + pub fn intersect_with(&mut self, other: &BitSet) { self.other_op(other, |w1, w2| w1 & w2); } @@ -1600,29 +1608,29 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{BitvSet, Bitv}; + /// use std::collections::{BitSet, BitVec}; /// /// let a = 0b01101000; /// let b = 0b10100000; /// let a_b = 0b01001000; // a - b /// let b_a = 0b10000000; // b - a /// - /// let mut bva = BitvSet::from_bitv(Bitv::from_bytes(&[a])); - /// let bvb = BitvSet::from_bitv(Bitv::from_bytes(&[b])); - /// let bva_b = BitvSet::from_bitv(Bitv::from_bytes(&[a_b])); - /// let bvb_a = BitvSet::from_bitv(Bitv::from_bytes(&[b_a])); + /// let mut bva = BitSet::from_bit_vec(BitVec::from_bytes(&[a])); + /// let bvb = BitSet::from_bit_vec(BitVec::from_bytes(&[b])); + /// let bva_b = BitSet::from_bit_vec(BitVec::from_bytes(&[a_b])); + /// let bvb_a = BitSet::from_bit_vec(BitVec::from_bytes(&[b_a])); /// /// bva.difference_with(&bvb); /// assert_eq!(bva, bva_b); /// - /// let bva = BitvSet::from_bitv(Bitv::from_bytes(&[a])); - /// let mut bvb = BitvSet::from_bitv(Bitv::from_bytes(&[b])); + /// let bva = BitSet::from_bit_vec(BitVec::from_bytes(&[a])); + /// let mut bvb = BitSet::from_bit_vec(BitVec::from_bytes(&[b])); /// /// bvb.difference_with(&bva); /// assert_eq!(bvb, bvb_a); /// ``` #[inline] - pub fn difference_with(&mut self, other: &BitvSet) { + pub fn difference_with(&mut self, other: &BitSet) { self.other_op(other, |w1, w2| w1 & !w2); } @@ -1632,21 +1640,21 @@ impl BitvSet { /// # Examples /// /// ``` - /// use std::collections::{BitvSet, Bitv}; + /// use std::collections::{BitSet, BitVec}; /// /// let a = 0b01101000; /// let b = 0b10100000; /// let res = 0b11001000; /// - /// let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[a])); - /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[b])); - /// let res = BitvSet::from_bitv(Bitv::from_bytes(&[res])); + /// let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[a])); + /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[b])); + /// let res = BitSet::from_bit_vec(BitVec::from_bytes(&[res])); /// /// a.symmetric_difference_with(&b); /// assert_eq!(a, res); /// ``` #[inline] - pub fn symmetric_difference_with(&mut self, other: &BitvSet) { + pub fn symmetric_difference_with(&mut self, other: &BitSet) { self.other_op(other, |w1, w2| w1 ^ w2); } @@ -1654,57 +1662,57 @@ impl BitvSet { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { - self.bitv.blocks().fold(0, |acc, n| acc + n.count_ones()) + self.bit_vec.blocks().fold(0, |acc, n| acc + n.count_ones()) } /// Returns whether there are no bits set in this set #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn is_empty(&self) -> bool { - self.bitv.none() + self.bit_vec.none() } /// Clears all bits in this set #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn clear(&mut self) { - self.bitv.clear(); + self.bit_vec.clear(); } /// Returns `true` if this set contains the specified integer. #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn contains(&self, value: &usize) -> bool { - let bitv = &self.bitv; - *value < bitv.nbits && bitv[*value] + let bit_vec = &self.bit_vec; + *value < bit_vec.nbits && bit_vec[*value] } /// Returns `true` if the set has no elements in common with `other`. /// This is equivalent to checking for an empty intersection. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_disjoint(&self, other: &BitvSet) -> bool { + pub fn is_disjoint(&self, other: &BitSet) -> bool { self.intersection(other).next().is_none() } /// Returns `true` if the set is a subset of another. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_subset(&self, other: &BitvSet) -> bool { - let self_bitv = &self.bitv; - let other_bitv = &other.bitv; - let other_blocks = blocks_for_bits(other_bitv.len()); + pub fn is_subset(&self, other: &BitSet) -> bool { + let self_bit_vec = &self.bit_vec; + let other_bit_vec = &other.bit_vec; + let other_blocks = blocks_for_bits(other_bit_vec.len()); // Check that `self` intersect `other` is self - self_bitv.blocks().zip(other_bitv.blocks()).all(|(w1, w2)| w1 & w2 == w1) && + self_bit_vec.blocks().zip(other_bit_vec.blocks()).all(|(w1, w2)| w1 & w2 == w1) && // Make sure if `self` has any more blocks than `other`, they're all 0 - self_bitv.blocks().skip(other_blocks).all(|w| w == 0) + self_bit_vec.blocks().skip(other_blocks).all(|w| w == 0) } /// Returns `true` if the set is a superset of another. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_superset(&self, other: &BitvSet) -> bool { + pub fn is_superset(&self, other: &BitSet) -> bool { other.is_subset(self) } @@ -1717,12 +1725,12 @@ impl BitvSet { } // Ensure we have enough space to hold the new element - let len = self.bitv.len(); + let len = self.bit_vec.len(); if value >= len { - self.bitv.grow(value - len + 1, false) + self.bit_vec.grow(value - len + 1, false) } - self.bitv.set(value, true); + self.bit_vec.set(value, true); return true; } @@ -1734,16 +1742,16 @@ impl BitvSet { return false; } - self.bitv.set(*value, false); + self.bit_vec.set(*value, false); return true; } } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for BitvSet { +impl fmt::Debug for BitSet { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - try!(write!(fmt, "BitvSet {{")); + try!(write!(fmt, "BitSet {{")); let mut first = true; for n in self { if !first { @@ -1756,7 +1764,7 @@ impl fmt::Debug for BitvSet { } } -impl hash::Hash for BitvSet { +impl hash::Hash for BitSet { fn hash(&self, state: &mut S) { for pos in self { pos.hash(state); @@ -1764,19 +1772,19 @@ impl hash::Hash for BitvSet { } } -/// An iterator for `BitvSet`. +/// An iterator for `BitSet`. #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct SetIter<'a> { - set: &'a BitvSet, + set: &'a BitSet, next_idx: usize } -/// An iterator combining two `BitvSet` iterators. +/// An iterator combining two `BitSet` iterators. #[derive(Clone)] struct TwoBitPositions<'a> { - set: &'a BitvSet, - other: &'a BitvSet, + set: &'a BitSet, + other: &'a BitSet, merge: fn(u32, u32) -> u32, current_word: u32, next_idx: usize @@ -1796,7 +1804,7 @@ impl<'a> Iterator for SetIter<'a> { type Item = usize; fn next(&mut self) -> Option { - while self.next_idx < self.set.bitv.len() { + while self.next_idx < self.set.bit_vec.len() { let idx = self.next_idx; self.next_idx += 1; @@ -1810,7 +1818,7 @@ impl<'a> Iterator for SetIter<'a> { #[inline] fn size_hint(&self) -> (usize, Option) { - (0, Some(self.set.bitv.len() - self.next_idx)) + (0, Some(self.set.bit_vec.len() - self.next_idx)) } } @@ -1819,20 +1827,20 @@ impl<'a> Iterator for TwoBitPositions<'a> { type Item = usize; fn next(&mut self) -> Option { - while self.next_idx < self.set.bitv.len() || - self.next_idx < self.other.bitv.len() { + while self.next_idx < self.set.bit_vec.len() || + self.next_idx < self.other.bit_vec.len() { let bit_idx = self.next_idx % u32::BITS; if bit_idx == 0 { - let s_bitv = &self.set.bitv; - let o_bitv = &self.other.bitv; + let s_bit_vec = &self.set.bit_vec; + let o_bit_vec = &self.other.bit_vec; // Merging the two words is a bit of an awkward dance since - // one Bitv might be longer than the other + // one BitVec might be longer than the other let word_idx = self.next_idx / u32::BITS; - let w1 = if word_idx < s_bitv.storage.len() { - s_bitv.storage[word_idx] + let w1 = if word_idx < s_bit_vec.storage.len() { + s_bit_vec.storage[word_idx] } else { 0 }; - let w2 = if word_idx < o_bitv.storage.len() { - o_bitv.storage[word_idx] + let w2 = if word_idx < o_bit_vec.storage.len() { + o_bit_vec.storage[word_idx] } else { 0 }; self.current_word = (self.merge)(w1, w2); } @@ -1847,7 +1855,7 @@ impl<'a> Iterator for TwoBitPositions<'a> { #[inline] fn size_hint(&self) -> (usize, Option) { - let cap = cmp::max(self.set.bitv.len(), self.other.bitv.len()); + let cap = cmp::max(self.set.bit_vec.len(), self.other.bit_vec.len()); (0, Some(cap - self.next_idx)) } } @@ -1885,7 +1893,7 @@ impl<'a> Iterator for SymmetricDifference<'a> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a> IntoIterator for &'a BitvSet { +impl<'a> IntoIterator for &'a BitSet { type Item = usize; type IntoIter = SetIter<'a>; @@ -1899,20 +1907,20 @@ mod tests { use prelude::*; use core::u32; - use super::Bitv; + use super::BitVec; #[test] fn test_to_str() { - let zerolen = Bitv::new(); + let zerolen = BitVec::new(); assert_eq!(format!("{:?}", zerolen), ""); - let eightbits = Bitv::from_elem(8, false); + let eightbits = BitVec::from_elem(8, false); assert_eq!(format!("{:?}", eightbits), "00000000") } #[test] fn test_0_elements() { - let act = Bitv::new(); + let act = BitVec::new(); let exp = Vec::new(); assert!(act.eq_vec(&exp)); assert!(act.none() && act.all()); @@ -1920,17 +1928,17 @@ mod tests { #[test] fn test_1_element() { - let mut act = Bitv::from_elem(1, false); + let mut act = BitVec::from_elem(1, false); assert!(act.eq_vec(&[false])); assert!(act.none() && !act.all()); - act = Bitv::from_elem(1, true); + act = BitVec::from_elem(1, true); assert!(act.eq_vec(&[true])); assert!(!act.none() && act.all()); } #[test] fn test_2_elements() { - let mut b = Bitv::from_elem(2, false); + let mut b = BitVec::from_elem(2, false); b.set(0, true); b.set(1, false); assert_eq!(format!("{:?}", b), "10"); @@ -1942,18 +1950,18 @@ mod tests { let mut act; // all 0 - act = Bitv::from_elem(10, false); + act = BitVec::from_elem(10, false); assert!((act.eq_vec( &[false, false, false, false, false, false, false, false, false, false]))); assert!(act.none() && !act.all()); // all 1 - act = Bitv::from_elem(10, true); + act = BitVec::from_elem(10, true); assert!((act.eq_vec(&[true, true, true, true, true, true, true, true, true, true]))); assert!(!act.none() && act.all()); // mixed - act = Bitv::from_elem(10, false); + act = BitVec::from_elem(10, false); act.set(0, true); act.set(1, true); act.set(2, true); @@ -1963,7 +1971,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(10, false); + act = BitVec::from_elem(10, false); act.set(5, true); act.set(6, true); act.set(7, true); @@ -1973,7 +1981,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(10, false); + act = BitVec::from_elem(10, false); act.set(0, true); act.set(3, true); act.set(6, true); @@ -1987,7 +1995,7 @@ mod tests { let mut act; // all 0 - act = Bitv::from_elem(31, false); + act = BitVec::from_elem(31, false); assert!(act.eq_vec( &[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, @@ -1995,7 +2003,7 @@ mod tests { assert!(act.none() && !act.all()); // all 1 - act = Bitv::from_elem(31, true); + act = BitVec::from_elem(31, true); assert!(act.eq_vec( &[true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, @@ -2003,7 +2011,7 @@ mod tests { assert!(!act.none() && act.all()); // mixed - act = Bitv::from_elem(31, false); + act = BitVec::from_elem(31, false); act.set(0, true); act.set(1, true); act.set(2, true); @@ -2019,7 +2027,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(31, false); + act = BitVec::from_elem(31, false); act.set(16, true); act.set(17, true); act.set(18, true); @@ -2035,7 +2043,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(31, false); + act = BitVec::from_elem(31, false); act.set(24, true); act.set(25, true); act.set(26, true); @@ -2050,7 +2058,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(31, false); + act = BitVec::from_elem(31, false); act.set(3, true); act.set(17, true); act.set(30, true); @@ -2066,7 +2074,7 @@ mod tests { let mut act; // all 0 - act = Bitv::from_elem(32, false); + act = BitVec::from_elem(32, false); assert!(act.eq_vec( &[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, @@ -2074,7 +2082,7 @@ mod tests { assert!(act.none() && !act.all()); // all 1 - act = Bitv::from_elem(32, true); + act = BitVec::from_elem(32, true); assert!(act.eq_vec( &[true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, @@ -2082,7 +2090,7 @@ mod tests { assert!(!act.none() && act.all()); // mixed - act = Bitv::from_elem(32, false); + act = BitVec::from_elem(32, false); act.set(0, true); act.set(1, true); act.set(2, true); @@ -2098,7 +2106,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(32, false); + act = BitVec::from_elem(32, false); act.set(16, true); act.set(17, true); act.set(18, true); @@ -2114,7 +2122,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(32, false); + act = BitVec::from_elem(32, false); act.set(24, true); act.set(25, true); act.set(26, true); @@ -2130,7 +2138,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(32, false); + act = BitVec::from_elem(32, false); act.set(3, true); act.set(17, true); act.set(30, true); @@ -2147,7 +2155,7 @@ mod tests { let mut act; // all 0 - act = Bitv::from_elem(33, false); + act = BitVec::from_elem(33, false); assert!(act.eq_vec( &[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, @@ -2155,7 +2163,7 @@ mod tests { assert!(act.none() && !act.all()); // all 1 - act = Bitv::from_elem(33, true); + act = BitVec::from_elem(33, true); assert!(act.eq_vec( &[true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, @@ -2163,7 +2171,7 @@ mod tests { assert!(!act.none() && act.all()); // mixed - act = Bitv::from_elem(33, false); + act = BitVec::from_elem(33, false); act.set(0, true); act.set(1, true); act.set(2, true); @@ -2179,7 +2187,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(33, false); + act = BitVec::from_elem(33, false); act.set(16, true); act.set(17, true); act.set(18, true); @@ -2195,7 +2203,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(33, false); + act = BitVec::from_elem(33, false); act.set(24, true); act.set(25, true); act.set(26, true); @@ -2211,7 +2219,7 @@ mod tests { assert!(!act.none() && !act.all()); // mixed - act = Bitv::from_elem(33, false); + act = BitVec::from_elem(33, false); act.set(3, true); act.set(17, true); act.set(30, true); @@ -2226,24 +2234,24 @@ mod tests { #[test] fn test_equal_differing_sizes() { - let v0 = Bitv::from_elem(10, false); - let v1 = Bitv::from_elem(11, false); + let v0 = BitVec::from_elem(10, false); + let v1 = BitVec::from_elem(11, false); assert!(v0 != v1); } #[test] fn test_equal_greatly_differing_sizes() { - let v0 = Bitv::from_elem(10, false); - let v1 = Bitv::from_elem(110, false); + let v0 = BitVec::from_elem(10, false); + let v1 = BitVec::from_elem(110, false); assert!(v0 != v1); } #[test] fn test_equal_sneaky_small() { - let mut a = Bitv::from_elem(1, false); + let mut a = BitVec::from_elem(1, false); a.set(0, true); - let mut b = Bitv::from_elem(1, true); + let mut b = BitVec::from_elem(1, true); b.set(0, true); assert_eq!(a, b); @@ -2251,12 +2259,12 @@ mod tests { #[test] fn test_equal_sneaky_big() { - let mut a = Bitv::from_elem(100, false); + let mut a = BitVec::from_elem(100, false); for i in 0..100 { a.set(i, true); } - let mut b = Bitv::from_elem(100, true); + let mut b = BitVec::from_elem(100, true); for i in 0..100 { b.set(i, true); } @@ -2266,18 +2274,18 @@ mod tests { #[test] fn test_from_bytes() { - let bitv = Bitv::from_bytes(&[0b10110110, 0b00000000, 0b11111111]); + let bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]); let str = concat!("10110110", "00000000", "11111111"); - assert_eq!(format!("{:?}", bitv), str); + assert_eq!(format!("{:?}", bit_vec), str); } #[test] fn test_to_bytes() { - let mut bv = Bitv::from_elem(3, true); + let mut bv = BitVec::from_elem(3, true); bv.set(1, false); assert_eq!(bv.to_bytes(), vec!(0b10100000)); - let mut bv = Bitv::from_elem(9, false); + let mut bv = BitVec::from_elem(9, false); bv.set(2, true); bv.set(8, true); assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000)); @@ -2286,32 +2294,32 @@ mod tests { #[test] fn test_from_bools() { let bools = vec![true, false, true, true]; - let bitv: Bitv = bools.iter().map(|n| *n).collect(); - assert_eq!(format!("{:?}", bitv), "1011"); + let bit_vec: BitVec = bools.iter().map(|n| *n).collect(); + assert_eq!(format!("{:?}", bit_vec), "1011"); } #[test] fn test_to_bools() { let bools = vec![false, false, true, false, false, true, true, false]; - assert_eq!(Bitv::from_bytes(&[0b00100110]).iter().collect::>(), bools); + assert_eq!(BitVec::from_bytes(&[0b00100110]).iter().collect::>(), bools); } #[test] - fn test_bitv_iterator() { + fn test_bit_vec_iterator() { let bools = vec![true, false, true, true]; - let bitv: Bitv = bools.iter().map(|n| *n).collect(); + let bit_vec: BitVec = bools.iter().map(|n| *n).collect(); - assert_eq!(bitv.iter().collect::>(), bools); + assert_eq!(bit_vec.iter().collect::>(), bools); let long: Vec<_> = (0i32..10000).map(|i| i % 2 == 0).collect(); - let bitv: Bitv = long.iter().map(|n| *n).collect(); - assert_eq!(bitv.iter().collect::>(), long) + let bit_vec: BitVec = long.iter().map(|n| *n).collect(); + assert_eq!(bit_vec.iter().collect::>(), long) } #[test] fn test_small_difference() { - let mut b1 = Bitv::from_elem(3, false); - let mut b2 = Bitv::from_elem(3, false); + let mut b1 = BitVec::from_elem(3, false); + let mut b2 = BitVec::from_elem(3, false); b1.set(0, true); b1.set(1, true); b2.set(1, true); @@ -2324,8 +2332,8 @@ mod tests { #[test] fn test_big_difference() { - let mut b1 = Bitv::from_elem(100, false); - let mut b2 = Bitv::from_elem(100, false); + let mut b1 = BitVec::from_elem(100, false); + let mut b2 = BitVec::from_elem(100, false); b1.set(0, true); b1.set(40, true); b2.set(40, true); @@ -2338,7 +2346,7 @@ mod tests { #[test] fn test_small_clear() { - let mut b = Bitv::from_elem(14, true); + let mut b = BitVec::from_elem(14, true); assert!(!b.none() && b.all()); b.clear(); assert!(b.none() && !b.all()); @@ -2346,16 +2354,16 @@ mod tests { #[test] fn test_big_clear() { - let mut b = Bitv::from_elem(140, true); + let mut b = BitVec::from_elem(140, true); assert!(!b.none() && b.all()); b.clear(); assert!(b.none() && !b.all()); } #[test] - fn test_bitv_lt() { - let mut a = Bitv::from_elem(5, false); - let mut b = Bitv::from_elem(5, false); + fn test_bit_vec_lt() { + let mut a = BitVec::from_elem(5, false); + let mut b = BitVec::from_elem(5, false); assert!(!(a < b) && !(b < a)); b.set(2, true); @@ -2370,8 +2378,8 @@ mod tests { #[test] fn test_ord() { - let mut a = Bitv::from_elem(5, false); - let mut b = Bitv::from_elem(5, false); + let mut a = BitVec::from_elem(5, false); + let mut b = BitVec::from_elem(5, false); assert!(a <= b && a >= b); a.set(1, true); @@ -2385,26 +2393,26 @@ mod tests { #[test] - fn test_small_bitv_tests() { - let v = Bitv::from_bytes(&[0]); + fn test_small_bit_vec_tests() { + let v = BitVec::from_bytes(&[0]); assert!(!v.all()); assert!(!v.any()); assert!(v.none()); - let v = Bitv::from_bytes(&[0b00010100]); + let v = BitVec::from_bytes(&[0b00010100]); assert!(!v.all()); assert!(v.any()); assert!(!v.none()); - let v = Bitv::from_bytes(&[0xFF]); + let v = BitVec::from_bytes(&[0xFF]); assert!(v.all()); assert!(v.any()); assert!(!v.none()); } #[test] - fn test_big_bitv_tests() { - let v = Bitv::from_bytes(&[ // 88 bits + fn test_big_bit_vec_tests() { + let v = BitVec::from_bytes(&[ // 88 bits 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); @@ -2412,7 +2420,7 @@ mod tests { assert!(!v.any()); assert!(v.none()); - let v = Bitv::from_bytes(&[ // 88 bits + let v = BitVec::from_bytes(&[ // 88 bits 0, 0, 0b00010100, 0, 0, 0, 0, 0b00110100, 0, 0, 0]); @@ -2420,7 +2428,7 @@ mod tests { assert!(v.any()); assert!(!v.none()); - let v = Bitv::from_bytes(&[ // 88 bits + let v = BitVec::from_bytes(&[ // 88 bits 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); @@ -2430,8 +2438,8 @@ mod tests { } #[test] - fn test_bitv_push_pop() { - let mut s = Bitv::from_elem(5 * u32::BITS - 2, false); + fn test_bit_vec_push_pop() { + let mut s = BitVec::from_elem(5 * u32::BITS - 2, false); assert_eq!(s.len(), 5 * u32::BITS - 2); assert_eq!(s[5 * u32::BITS - 3], false); s.push(true); @@ -2453,29 +2461,29 @@ mod tests { } #[test] - fn test_bitv_truncate() { - let mut s = Bitv::from_elem(5 * u32::BITS, true); + fn test_bit_vec_truncate() { + let mut s = BitVec::from_elem(5 * u32::BITS, true); - assert_eq!(s, Bitv::from_elem(5 * u32::BITS, true)); + assert_eq!(s, BitVec::from_elem(5 * u32::BITS, true)); assert_eq!(s.len(), 5 * u32::BITS); s.truncate(4 * u32::BITS); - assert_eq!(s, Bitv::from_elem(4 * u32::BITS, true)); + assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true)); assert_eq!(s.len(), 4 * u32::BITS); // Truncating to a size > s.len() should be a noop s.truncate(5 * u32::BITS); - assert_eq!(s, Bitv::from_elem(4 * u32::BITS, true)); + assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true)); assert_eq!(s.len(), 4 * u32::BITS); s.truncate(3 * u32::BITS - 10); - assert_eq!(s, Bitv::from_elem(3 * u32::BITS - 10, true)); + assert_eq!(s, BitVec::from_elem(3 * u32::BITS - 10, true)); assert_eq!(s.len(), 3 * u32::BITS - 10); s.truncate(0); - assert_eq!(s, Bitv::from_elem(0, true)); + assert_eq!(s, BitVec::from_elem(0, true)); assert_eq!(s.len(), 0); } #[test] - fn test_bitv_reserve() { - let mut s = Bitv::from_elem(5 * u32::BITS, true); + fn test_bit_vec_reserve() { + let mut s = BitVec::from_elem(5 * u32::BITS, true); // Check capacity assert!(s.capacity() >= 5 * u32::BITS); s.reserve(2 * u32::BITS); @@ -2498,25 +2506,25 @@ mod tests { } #[test] - fn test_bitv_grow() { - let mut bitv = Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010]); - bitv.grow(32, true); - assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010, + fn test_bit_vec_grow() { + let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010]); + bit_vec.grow(32, true); + assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010, 0xFF, 0xFF, 0xFF, 0xFF])); - bitv.grow(64, false); - assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010, + bit_vec.grow(64, false); + assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0])); - bitv.grow(16, true); - assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010, + bit_vec.grow(16, true); + assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF])); } #[test] - fn test_bitv_extend() { - let mut bitv = Bitv::from_bytes(&[0b10110110, 0b00000000, 0b11111111]); - let ext = Bitv::from_bytes(&[0b01001001, 0b10010010, 0b10111101]); - bitv.extend(ext.iter()); - assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b11111111, + fn test_bit_vec_extend() { + let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]); + let ext = BitVec::from_bytes(&[0b01001001, 0b10010010, 0b10111101]); + bit_vec.extend(ext.iter()); + assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111, 0b01001001, 0b10010010, 0b10111101])); } } @@ -2525,14 +2533,14 @@ mod tests { #[cfg(test)] -mod bitv_bench { +mod bit_vec_bench { use std::prelude::v1::*; use std::rand; use std::rand::Rng; use std::u32; use test::{Bencher, black_box}; - use super::Bitv; + use super::BitVec; static BENCH_BITS : usize = 1 << 14; @@ -2544,67 +2552,67 @@ mod bitv_bench { #[bench] fn bench_usize_small(b: &mut Bencher) { let mut r = rng(); - let mut bitv = 0 as usize; + let mut bit_vec = 0 as usize; b.iter(|| { for _ in 0..100 { - bitv |= 1 << ((r.next_u32() as usize) % u32::BITS); + bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS); } - black_box(&bitv); + black_box(&bit_vec); }); } #[bench] - fn bench_bitv_set_big_fixed(b: &mut Bencher) { + fn bench_bit_set_big_fixed(b: &mut Bencher) { let mut r = rng(); - let mut bitv = Bitv::from_elem(BENCH_BITS, false); + let mut bit_vec = BitVec::from_elem(BENCH_BITS, false); b.iter(|| { for _ in 0..100 { - bitv.set((r.next_u32() as usize) % BENCH_BITS, true); + bit_vec.set((r.next_u32() as usize) % BENCH_BITS, true); } - black_box(&bitv); + black_box(&bit_vec); }); } #[bench] - fn bench_bitv_set_big_variable(b: &mut Bencher) { + fn bench_bit_set_big_variable(b: &mut Bencher) { let mut r = rng(); - let mut bitv = Bitv::from_elem(BENCH_BITS, false); + let mut bit_vec = BitVec::from_elem(BENCH_BITS, false); b.iter(|| { for _ in 0..100 { - bitv.set((r.next_u32() as usize) % BENCH_BITS, r.gen()); + bit_vec.set((r.next_u32() as usize) % BENCH_BITS, r.gen()); } - black_box(&bitv); + black_box(&bit_vec); }); } #[bench] - fn bench_bitv_set_small(b: &mut Bencher) { + fn bench_bit_set_small(b: &mut Bencher) { let mut r = rng(); - let mut bitv = Bitv::from_elem(u32::BITS, false); + let mut bit_vec = BitVec::from_elem(u32::BITS, false); b.iter(|| { for _ in 0..100 { - bitv.set((r.next_u32() as usize) % u32::BITS, true); + bit_vec.set((r.next_u32() as usize) % u32::BITS, true); } - black_box(&bitv); + black_box(&bit_vec); }); } #[bench] - fn bench_bitv_big_union(b: &mut Bencher) { - let mut b1 = Bitv::from_elem(BENCH_BITS, false); - let b2 = Bitv::from_elem(BENCH_BITS, false); + fn bench_bit_vec_big_union(b: &mut Bencher) { + let mut b1 = BitVec::from_elem(BENCH_BITS, false); + let b2 = BitVec::from_elem(BENCH_BITS, false); b.iter(|| { b1.union(&b2) }) } #[bench] - fn bench_bitv_small_iter(b: &mut Bencher) { - let bitv = Bitv::from_elem(u32::BITS, false); + fn bench_bit_vec_small_iter(b: &mut Bencher) { + let bit_vec = BitVec::from_elem(u32::BITS, false); b.iter(|| { let mut sum = 0; for _ in 0..10 { - for pres in &bitv { + for pres in &bit_vec { sum += pres as usize; } } @@ -2613,11 +2621,11 @@ mod bitv_bench { } #[bench] - fn bench_bitv_big_iter(b: &mut Bencher) { - let bitv = Bitv::from_elem(BENCH_BITS, false); + fn bench_bit_vec_big_iter(b: &mut Bencher) { + let bit_vec = BitVec::from_elem(BENCH_BITS, false); b.iter(|| { let mut sum = 0; - for pres in &bitv { + for pres in &bit_vec { sum += pres as usize; } sum @@ -2632,27 +2640,27 @@ mod bitv_bench { #[cfg(test)] -mod bitv_set_test { +mod bit_set_test { use prelude::*; use std::iter::range_step; - use super::{Bitv, BitvSet}; + use super::{BitVec, BitSet}; #[test] - fn test_bitv_set_show() { - let mut s = BitvSet::new(); + fn test_bit_set_show() { + let mut s = BitSet::new(); s.insert(1); s.insert(10); s.insert(50); s.insert(2); - assert_eq!("BitvSet {1, 2, 10, 50}", format!("{:?}", s)); + assert_eq!("BitSet {1, 2, 10, 50}", format!("{:?}", s)); } #[test] - fn test_bitv_set_from_usizes() { + fn test_bit_set_from_usizes() { let usizes = vec![0, 2, 2, 3]; - let a: BitvSet = usizes.into_iter().collect(); - let mut b = BitvSet::new(); + let a: BitSet = usizes.into_iter().collect(); + let mut b = BitSet::new(); b.insert(0); b.insert(2); b.insert(3); @@ -2660,14 +2668,14 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_iterator() { + fn test_bit_set_iterator() { let usizes = vec![0, 2, 2, 3]; - let bitv: BitvSet = usizes.into_iter().collect(); + let bit_vec: BitSet = usizes.into_iter().collect(); - let idxs: Vec<_> = bitv.iter().collect(); + let idxs: Vec<_> = bit_vec.iter().collect(); assert_eq!(idxs, vec![0, 2, 3]); - let long: BitvSet = (0..10000).filter(|&n| n % 2 == 0).collect(); + let long: BitSet = (0..10000).filter(|&n| n % 2 == 0).collect(); let real: Vec<_> = range_step(0, 10000, 2).collect(); let idxs: Vec<_> = long.iter().collect(); @@ -2675,12 +2683,12 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_frombitv_init() { + fn test_bit_set_frombit_vec_init() { let bools = [true, false]; let lengths = [10, 64, 100]; for &b in &bools { for &l in &lengths { - let bitset = BitvSet::from_bitv(Bitv::from_elem(l, b)); + let bitset = BitSet::from_bit_vec(BitVec::from_elem(l, b)); assert_eq!(bitset.contains(&1), b); assert_eq!(bitset.contains(&(l-1)), b); assert!(!bitset.contains(&l)); @@ -2689,9 +2697,9 @@ mod bitv_set_test { } #[test] - fn test_bitv_masking() { - let b = Bitv::from_elem(140, true); - let mut bs = BitvSet::from_bitv(b); + fn test_bit_vec_masking() { + let b = BitVec::from_elem(140, true); + let mut bs = BitSet::from_bit_vec(b); assert!(bs.contains(&139)); assert!(!bs.contains(&140)); assert!(bs.insert(150)); @@ -2702,8 +2710,8 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_basic() { - let mut b = BitvSet::new(); + fn test_bit_set_basic() { + let mut b = BitSet::new(); assert!(b.insert(3)); assert!(!b.insert(3)); assert!(b.contains(&3)); @@ -2717,9 +2725,9 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_intersection() { - let mut a = BitvSet::new(); - let mut b = BitvSet::new(); + fn test_bit_set_intersection() { + let mut a = BitSet::new(); + let mut b = BitSet::new(); assert!(a.insert(11)); assert!(a.insert(1)); @@ -2740,9 +2748,9 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_difference() { - let mut a = BitvSet::new(); - let mut b = BitvSet::new(); + fn test_bit_set_difference() { + let mut a = BitSet::new(); + let mut b = BitSet::new(); assert!(a.insert(1)); assert!(a.insert(3)); @@ -2759,9 +2767,9 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_symmetric_difference() { - let mut a = BitvSet::new(); - let mut b = BitvSet::new(); + fn test_bit_set_symmetric_difference() { + let mut a = BitSet::new(); + let mut b = BitSet::new(); assert!(a.insert(1)); assert!(a.insert(3)); @@ -2780,9 +2788,9 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_union() { - let mut a = BitvSet::new(); - let mut b = BitvSet::new(); + fn test_bit_set_union() { + let mut a = BitSet::new(); + let mut b = BitSet::new(); assert!(a.insert(1)); assert!(a.insert(3)); assert!(a.insert(5)); @@ -2805,9 +2813,9 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_subset() { - let mut set1 = BitvSet::new(); - let mut set2 = BitvSet::new(); + fn test_bit_set_subset() { + let mut set1 = BitSet::new(); + let mut set2 = BitSet::new(); assert!(set1.is_subset(&set2)); // {} {} set2.insert(100); @@ -2831,11 +2839,11 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_is_disjoint() { - let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01000000])); - let c = BitvSet::new(); - let d = BitvSet::from_bitv(Bitv::from_bytes(&[0b00110000])); + fn test_bit_set_is_disjoint() { + let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01000000])); + let c = BitSet::new(); + let d = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00110000])); assert!(!a.is_disjoint(&d)); assert!(!d.is_disjoint(&a)); @@ -2849,19 +2857,19 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_union_with() { + fn test_bit_set_union_with() { //a should grow to include larger elements - let mut a = BitvSet::new(); + let mut a = BitSet::new(); a.insert(0); - let mut b = BitvSet::new(); + let mut b = BitSet::new(); b.insert(5); - let expected = BitvSet::from_bitv(Bitv::from_bytes(&[0b10000100])); + let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100])); a.union_with(&b); assert_eq!(a, expected); // Standard - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01100010])); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010])); let c = a.clone(); a.union_with(&b); b.union_with(&c); @@ -2870,10 +2878,10 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_intersect_with() { + fn test_bit_set_intersect_with() { // Explicitly 0'ed bits - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000])); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000])); let c = a.clone(); a.intersect_with(&b); b.intersect_with(&c); @@ -2881,8 +2889,8 @@ mod bitv_set_test { assert!(b.is_empty()); // Uninitialized bits should behave like 0's - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let mut b = BitvSet::new(); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let mut b = BitSet::new(); let c = a.clone(); a.intersect_with(&b); b.intersect_with(&c); @@ -2890,8 +2898,8 @@ mod bitv_set_test { assert!(b.is_empty()); // Standard - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01100010])); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010])); let c = a.clone(); a.intersect_with(&b); b.intersect_with(&c); @@ -2900,22 +2908,22 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_difference_with() { + fn test_bit_set_difference_with() { // Explicitly 0'ed bits - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000])); - let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000])); + let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); a.difference_with(&b); assert!(a.is_empty()); // Uninitialized bits should behave like 0's - let mut a = BitvSet::new(); - let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b11111111])); + let mut a = BitSet::new(); + let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11111111])); a.difference_with(&b); assert!(a.is_empty()); // Standard - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01100010])); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010])); let c = a.clone(); a.difference_with(&b); b.difference_with(&c); @@ -2924,27 +2932,27 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_symmetric_difference_with() { + fn test_bit_set_symmetric_difference_with() { //a should grow to include larger elements - let mut a = BitvSet::new(); + let mut a = BitSet::new(); a.insert(0); a.insert(1); - let mut b = BitvSet::new(); + let mut b = BitSet::new(); b.insert(1); b.insert(5); - let expected = BitvSet::from_bitv(Bitv::from_bytes(&[0b10000100])); + let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100])); a.symmetric_difference_with(&b); assert_eq!(a, expected); - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let b = BitvSet::new(); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let b = BitSet::new(); let c = a.clone(); a.symmetric_difference_with(&b); assert_eq!(a, c); // Standard - let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b11100010])); - let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101010])); + let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11100010])); + let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101010])); let c = a.clone(); a.symmetric_difference_with(&b); b.symmetric_difference_with(&c); @@ -2953,10 +2961,10 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_eq() { - let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000])); - let c = BitvSet::new(); + fn test_bit_set_eq() { + let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000])); + let c = BitSet::new(); assert!(a == a); assert!(a != b); @@ -2967,10 +2975,10 @@ mod bitv_set_test { } #[test] - fn test_bitv_set_cmp() { - let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010])); - let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000])); - let c = BitvSet::new(); + fn test_bit_set_cmp() { + let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010])); + let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000])); + let c = BitSet::new(); assert_eq!(a.cmp(&b), Greater); assert_eq!(a.cmp(&c), Greater); @@ -2981,8 +2989,8 @@ mod bitv_set_test { } #[test] - fn test_bitv_remove() { - let mut a = BitvSet::new(); + fn test_bit_vec_remove() { + let mut a = BitSet::new(); assert!(a.insert(1)); assert!(a.remove(&1)); @@ -2996,8 +3004,8 @@ mod bitv_set_test { } #[test] - fn test_bitv_clone() { - let mut a = BitvSet::new(); + fn test_bit_vec_clone() { + let mut a = BitSet::new(); assert!(a.insert(1)); assert!(a.insert(100)); @@ -3020,14 +3028,14 @@ mod bitv_set_test { #[cfg(test)] -mod bitv_set_bench { +mod bit_set_bench { use std::prelude::v1::*; use std::rand; use std::rand::Rng; use std::u32; use test::{Bencher, black_box}; - use super::{Bitv, BitvSet}; + use super::{BitVec, BitSet}; static BENCH_BITS : usize = 1 << 14; @@ -3037,36 +3045,36 @@ mod bitv_set_bench { } #[bench] - fn bench_bitvset_small(b: &mut Bencher) { + fn bench_bit_vecset_small(b: &mut Bencher) { let mut r = rng(); - let mut bitv = BitvSet::new(); + let mut bit_vec = BitSet::new(); b.iter(|| { for _ in 0..100 { - bitv.insert((r.next_u32() as usize) % u32::BITS); + bit_vec.insert((r.next_u32() as usize) % u32::BITS); } - black_box(&bitv); + black_box(&bit_vec); }); } #[bench] - fn bench_bitvset_big(b: &mut Bencher) { + fn bench_bit_vecset_big(b: &mut Bencher) { let mut r = rng(); - let mut bitv = BitvSet::new(); + let mut bit_vec = BitSet::new(); b.iter(|| { for _ in 0..100 { - bitv.insert((r.next_u32() as usize) % BENCH_BITS); + bit_vec.insert((r.next_u32() as usize) % BENCH_BITS); } - black_box(&bitv); + black_box(&bit_vec); }); } #[bench] - fn bench_bitvset_iter(b: &mut Bencher) { - let bitv = BitvSet::from_bitv(Bitv::from_fn(BENCH_BITS, + fn bench_bit_vecset_iter(b: &mut Bencher) { + let bit_vec = BitSet::from_bit_vec(BitVec::from_fn(BENCH_BITS, |idx| {idx % 3 == 0})); b.iter(|| { let mut sum = 0; - for idx in &bitv { + for idx in &bit_vec { sum += idx as usize; } sum diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 747211e923859..96052156df03e 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -29,7 +29,7 @@ use core::ops::{Index, IndexMut}; use core::{iter, fmt, mem}; use Bound::{self, Included, Excluded, Unbounded}; -use ring_buf::RingBuf; +use vec_deque::VecDeque; use self::Continuation::{Continue, Finished}; use self::StackOp::*; @@ -75,7 +75,7 @@ pub struct BTreeMap { /// An abstract base over-which all other BTree iterators are built. struct AbsIter { - traversals: RingBuf, + traversals: VecDeque, size: usize, } @@ -1189,7 +1189,7 @@ impl BTreeMap { pub fn iter(&self) -> Iter { let len = self.len(); // NB. The initial capacity for ringbuf is large enough to avoid reallocs in many cases. - let mut lca = RingBuf::new(); + let mut lca = VecDeque::new(); lca.push_back(Traverse::traverse(&self.root)); Iter { inner: AbsIter { @@ -1221,7 +1221,7 @@ impl BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] pub fn iter_mut(&mut self) -> IterMut { let len = self.len(); - let mut lca = RingBuf::new(); + let mut lca = VecDeque::new(); lca.push_back(Traverse::traverse(&mut self.root)); IterMut { inner: AbsIter { @@ -1250,7 +1250,7 @@ impl BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] pub fn into_iter(self) -> IntoIter { let len = self.len(); - let mut lca = RingBuf::new(); + let mut lca = VecDeque::new(); lca.push_back(Traverse::traverse(self.root)); IntoIter { inner: AbsIter { @@ -1342,7 +1342,7 @@ macro_rules! range_impl { // A deque that encodes two search paths containing (left-to-right): // a series of truncated-from-the-left iterators, the LCA's doubly-truncated iterator, // and a series of truncated-from-the-right iterators. - let mut traversals = RingBuf::new(); + let mut traversals = VecDeque::new(); let (root, min, max) = ($root, $min, $max); let mut leftmost = None; diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index cacbf3bce80f0..b9f50fc385b53 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -49,17 +49,33 @@ extern crate alloc; #[cfg(test)] #[macro_use] extern crate log; pub use binary_heap::BinaryHeap; -pub use bitv::Bitv; -pub use bitv_set::BitvSet; +pub use bit_vec::BitVec; +pub use bit_set::BitSet; pub use btree_map::BTreeMap; pub use btree_set::BTreeSet; -pub use dlist::DList; +pub use linked_list::LinkedList; pub use enum_set::EnumSet; -pub use ring_buf::RingBuf; +pub use vec_deque::VecDeque; pub use string::String; pub use vec::Vec; pub use vec_map::VecMap; +#[deprecated(since = "1.0.0", reason = "renamed to vec_deque")] +#[unstable(feature = "collections")] +pub use vec_deque as ring_buf; + +#[deprecated(since = "1.0.0", reason = "renamed to linked_list")] +#[unstable(feature = "collections")] +pub use linked_list as dlist; + +#[deprecated(since = "1.0.0", reason = "renamed to bit_vec")] +#[unstable(feature = "collections")] +pub use bit_vec as bitv; + +#[deprecated(since = "1.0.0", reason = "renamed to bit_set")] +#[unstable(feature = "collections")] +pub use bit_set as bitv_set; + // Needed for the vec! macro pub use alloc::boxed; @@ -71,10 +87,10 @@ mod macros; pub mod binary_heap; mod bit; mod btree; -pub mod dlist; +pub mod linked_list; pub mod enum_set; pub mod fmt; -pub mod ring_buf; +pub mod vec_deque; pub mod slice; pub mod str; pub mod string; @@ -83,15 +99,23 @@ pub mod vec_map; #[unstable(feature = "collections", reason = "RFC 509")] -pub mod bitv { - pub use bit::{Bitv, Iter}; +pub mod bit_vec { + pub use bit::{BitVec, Iter}; + + #[deprecated(since = "1.0.0", reason = "renamed to BitVec")] + #[unstable(feature = "collections")] + pub use bit::BitVec as Bitv; } #[unstable(feature = "collections", reason = "RFC 509")] -pub mod bitv_set { - pub use bit::{BitvSet, Union, Intersection, Difference, SymmetricDifference}; +pub mod bit_set { + pub use bit::{BitSet, Union, Intersection, Difference, SymmetricDifference}; pub use bit::SetIter as Iter; + + #[deprecated(since = "1.0.0", reason = "renamed to BitSet")] + #[unstable(feature = "collections")] + pub use bit::BitSet as BitvSet; } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcollections/dlist.rs b/src/libcollections/linked_list.rs similarity index 86% rename from src/libcollections/dlist.rs rename to src/libcollections/linked_list.rs index eb1bf93c0aafc..550c1450b93af 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/linked_list.rs @@ -10,13 +10,13 @@ //! A doubly-linked list with owned nodes. //! -//! The `DList` allows pushing and popping elements at either end and is thus +//! The `LinkedList` allows pushing and popping elements at either end and is thus //! efficiently usable as a double-ended queue. -// DList is constructed like a singly-linked list over the field `next`. +// LinkedList is constructed like a singly-linked list over the field `next`. // including the last link being None; each Node owns its `next` field. // -// Backlinks over DList::prev are raw pointers that form a full chain in +// Backlinks over LinkedList::prev are raw pointers that form a full chain in // the reverse direction. #![stable(feature = "rust1", since = "1.0.0")] @@ -32,9 +32,13 @@ use core::iter::{self, FromIterator, IntoIterator}; use core::mem; use core::ptr; +#[deprecated(since = "1.0.0", reason = "renamed to LinkedList")] +#[unstable(feature = "collections")] +pub use LinkedList as DList; + /// A doubly-linked list. #[stable(feature = "rust1", since = "1.0.0")] -pub struct DList { +pub struct LinkedList { length: usize, list_head: Link, list_tail: Rawlink>, @@ -56,7 +60,7 @@ struct Node { value: T, } -/// An iterator over references to the items of a `DList`. +/// An iterator over references to the items of a `LinkedList`. #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, T:'a> { head: &'a Link, @@ -76,20 +80,20 @@ impl<'a, T> Clone for Iter<'a, T> { } } -/// An iterator over mutable references to the items of a `DList`. +/// An iterator over mutable references to the items of a `LinkedList`. #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, T:'a> { - list: &'a mut DList, + list: &'a mut LinkedList, head: Rawlink>, tail: Rawlink>, nelem: usize, } -/// An iterator over mutable references to the items of a `DList`. +/// An iterator over mutable references to the items of a `LinkedList`. #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { - list: DList + list: LinkedList } /// Rawlink is a type like Option but for holding a raw pointer @@ -147,7 +151,7 @@ fn link_with_prev(mut next: Box>, prev: Rawlink>) } // private methods -impl DList { +impl LinkedList { /// Add a Node first in the list #[inline] fn push_front_node(&mut self, mut new_head: Box>) { @@ -207,18 +211,18 @@ impl DList { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for DList { +impl Default for LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn default() -> DList { DList::new() } + fn default() -> LinkedList { LinkedList::new() } } -impl DList { - /// Creates an empty `DList`. +impl LinkedList { + /// Creates an empty `LinkedList`. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> DList { - DList{list_head: None, list_tail: Rawlink::none(), length: 0} + pub fn new() -> LinkedList { + LinkedList{list_head: None, list_tail: Rawlink::none(), length: 0} } /// Moves all elements from `other` to the end of the list. @@ -231,10 +235,10 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut a = DList::new(); - /// let mut b = DList::new(); + /// let mut a = LinkedList::new(); + /// let mut b = LinkedList::new(); /// a.push_back(1); /// a.push_back(2); /// b.push_back(3); @@ -247,7 +251,7 @@ impl DList { /// } /// println!("{}", b.len()); // prints 0 /// ``` - pub fn append(&mut self, other: &mut DList) { + pub fn append(&mut self, other: &mut LinkedList) { match self.list_tail.resolve() { None => { self.length = other.length; @@ -301,16 +305,16 @@ impl DList { IntoIter{list: self} } - /// Returns `true` if the `DList` is empty. + /// Returns `true` if the `LinkedList` is empty. /// /// This operation should compute in O(1) time. /// /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// assert!(dl.is_empty()); /// /// dl.push_front("foo"); @@ -322,16 +326,16 @@ impl DList { self.list_head.is_none() } - /// Returns the length of the `DList`. + /// Returns the length of the `LinkedList`. /// /// This operation should compute in O(1) time. /// /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// /// dl.push_front(2); /// assert_eq!(dl.len(), 1); @@ -349,16 +353,16 @@ impl DList { self.length } - /// Removes all elements from the `DList`. + /// Removes all elements from the `LinkedList`. /// /// This operation should compute in O(n) time. /// /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// /// dl.push_front(2); /// dl.push_front(1); @@ -373,7 +377,7 @@ impl DList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn clear(&mut self) { - *self = DList::new() + *self = LinkedList::new() } /// Provides a reference to the front element, or `None` if the list is @@ -382,9 +386,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// assert_eq!(dl.front(), None); /// /// dl.push_front(1); @@ -403,9 +407,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// assert_eq!(dl.front(), None); /// /// dl.push_front(1); @@ -430,9 +434,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// assert_eq!(dl.back(), None); /// /// dl.push_back(1); @@ -451,9 +455,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// assert_eq!(dl.back(), None); /// /// dl.push_back(1); @@ -479,9 +483,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut dl = DList::new(); + /// let mut dl = LinkedList::new(); /// /// dl.push_front(2); /// assert_eq!(dl.front().unwrap(), &2); @@ -503,9 +507,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut d = DList::new(); + /// let mut d = LinkedList::new(); /// assert_eq!(d.pop_front(), None); /// /// d.push_front(1); @@ -526,9 +530,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut d = DList::new(); + /// let mut d = LinkedList::new(); /// d.push_back(1); /// d.push_back(3); /// assert_eq!(3, *d.back().unwrap()); @@ -544,9 +548,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut d = DList::new(); + /// let mut d = LinkedList::new(); /// assert_eq!(d.pop_back(), None); /// d.push_back(1); /// d.push_back(3); @@ -569,9 +573,9 @@ impl DList { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut d = DList::new(); + /// let mut d = LinkedList::new(); /// /// d.push_front(1); /// d.push_front(2); @@ -583,13 +587,13 @@ impl DList { /// assert_eq!(splitted.pop_front(), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn split_off(&mut self, at: usize) -> DList { + pub fn split_off(&mut self, at: usize) -> LinkedList { let len = self.len(); assert!(at <= len, "Cannot split off at a nonexistent index"); if at == 0 { - return mem::replace(self, DList::new()); + return mem::replace(self, LinkedList::new()); } else if at == len { - return DList::new(); + return LinkedList::new(); } // Below, we iterate towards the `i-1`th node, either from the start or the end, @@ -612,7 +616,7 @@ impl DList { iter.tail }; - let mut splitted_list = DList { + let mut splitted_list = LinkedList { list_head: None, list_tail: self.list_tail, length: len - at @@ -628,9 +632,9 @@ impl DList { #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for DList { +impl Drop for LinkedList { fn drop(&mut self) { - // Dissolve the dlist in backwards direction + // Dissolve the linked_list in backwards direction // Just dropping the list_head can lead to stack exhaustion // when length is >> 1_000_000 let mut tail = self.list_tail; @@ -761,9 +765,9 @@ impl<'a, A> IterMut<'a, A> { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut list: DList<_> = vec![1, 3, 4].into_iter().collect(); + /// let mut list: LinkedList<_> = vec![1, 3, 4].into_iter().collect(); /// /// { /// let mut it = list.iter_mut(); @@ -788,9 +792,9 @@ impl<'a, A> IterMut<'a, A> { /// # Examples /// /// ``` - /// use std::collections::DList; + /// use std::collections::LinkedList; /// - /// let mut list: DList<_> = vec![1, 2, 3].into_iter().collect(); + /// let mut list: LinkedList<_> = vec![1, 2, 3].into_iter().collect(); /// /// let mut it = list.iter_mut(); /// assert_eq!(it.next().unwrap(), &1); @@ -829,16 +833,16 @@ impl DoubleEndedIterator for IntoIter { } #[stable(feature = "rust1", since = "1.0.0")] -impl FromIterator for DList { - fn from_iter>(iterator: T) -> DList { - let mut ret = DList::new(); +impl FromIterator for LinkedList { + fn from_iter>(iterator: T) -> LinkedList { + let mut ret = LinkedList::new(); ret.extend(iterator); ret } } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for DList { +impl IntoIterator for LinkedList { type Item = T; type IntoIter = IntoIter; @@ -848,7 +852,7 @@ impl IntoIterator for DList { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a DList { +impl<'a, T> IntoIterator for &'a LinkedList { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -857,7 +861,7 @@ impl<'a, T> IntoIterator for &'a DList { } } -impl<'a, T> IntoIterator for &'a mut DList { +impl<'a, T> IntoIterator for &'a mut LinkedList { type Item = &'a mut T; type IntoIter = IterMut<'a, T>; @@ -867,54 +871,54 @@ impl<'a, T> IntoIterator for &'a mut DList { } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for DList { +impl Extend for LinkedList { fn extend>(&mut self, iterator: T) { for elt in iterator { self.push_back(elt); } } } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for DList { - fn eq(&self, other: &DList) -> bool { +impl PartialEq for LinkedList { + fn eq(&self, other: &LinkedList) -> bool { self.len() == other.len() && iter::order::eq(self.iter(), other.iter()) } - fn ne(&self, other: &DList) -> bool { + fn ne(&self, other: &LinkedList) -> bool { self.len() != other.len() || iter::order::ne(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for DList {} +impl Eq for LinkedList {} #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for DList { - fn partial_cmp(&self, other: &DList) -> Option { +impl PartialOrd for LinkedList { + fn partial_cmp(&self, other: &LinkedList) -> Option { iter::order::partial_cmp(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for DList { +impl Ord for LinkedList { #[inline] - fn cmp(&self, other: &DList) -> Ordering { + fn cmp(&self, other: &LinkedList) -> Ordering { iter::order::cmp(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for DList { - fn clone(&self) -> DList { +impl Clone for LinkedList { + fn clone(&self) -> LinkedList { self.iter().map(|x| x.clone()).collect() } } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for DList { +impl fmt::Debug for LinkedList { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "DList [")); + try!(write!(f, "LinkedList [")); for (i, e) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -926,7 +930,7 @@ impl fmt::Debug for DList { } #[stable(feature = "rust1", since = "1.0.0")] -impl> Hash for DList { +impl> Hash for LinkedList { fn hash(&self, state: &mut S) { self.len().hash(state); for elt in self { @@ -944,9 +948,9 @@ mod tests { use test::Bencher; use test; - use super::{DList, Node}; + use super::{LinkedList, Node}; - pub fn check_links(list: &DList) { + pub fn check_links(list: &LinkedList) { let mut len = 0; let mut last_ptr: Option<&Node> = None; let mut node_ptr: &Node; @@ -980,7 +984,7 @@ mod tests { #[test] fn test_basic() { - let mut m = DList::new(); + let mut m = LinkedList::new(); assert_eq!(m.pop_front(), None); assert_eq!(m.pop_back(), None); assert_eq!(m.pop_front(), None); @@ -999,7 +1003,7 @@ mod tests { m.push_back(box 7); assert_eq!(m.pop_front(), Some(box 1)); - let mut n = DList::new(); + let mut n = LinkedList::new(); n.push_front(2); n.push_front(3); { @@ -1019,12 +1023,12 @@ mod tests { } #[cfg(test)] - fn generate_test() -> DList { + fn generate_test() -> LinkedList { list_from(&[0,1,2,3,4,5,6]) } #[cfg(test)] - fn list_from(v: &[T]) -> DList { + fn list_from(v: &[T]) -> LinkedList { v.iter().map(|x| (*x).clone()).collect() } @@ -1032,8 +1036,8 @@ mod tests { fn test_append() { // Empty to empty { - let mut m = DList::::new(); - let mut n = DList::new(); + let mut m = LinkedList::::new(); + let mut n = LinkedList::new(); m.append(&mut n); check_links(&m); assert_eq!(m.len(), 0); @@ -1041,8 +1045,8 @@ mod tests { } // Non-empty to empty { - let mut m = DList::new(); - let mut n = DList::new(); + let mut m = LinkedList::new(); + let mut n = LinkedList::new(); n.push_back(2); m.append(&mut n); check_links(&m); @@ -1053,8 +1057,8 @@ mod tests { } // Empty to non-empty { - let mut m = DList::new(); - let mut n = DList::new(); + let mut m = LinkedList::new(); + let mut n = LinkedList::new(); m.push_back(2); m.append(&mut n); check_links(&m); @@ -1089,7 +1093,7 @@ mod tests { fn test_split_off() { // singleton { - let mut m = DList::new(); + let mut m = LinkedList::new(); m.push_back(1); let p = m.split_off(0); @@ -1130,7 +1134,7 @@ mod tests { // no-op on the last index { - let mut m = DList::new(); + let mut m = LinkedList::new(); m.push_back(1); let p = m.split_off(1); @@ -1148,7 +1152,7 @@ mod tests { for (i, elt) in m.iter().enumerate() { assert_eq!(i as i32, *elt); } - let mut n = DList::new(); + let mut n = LinkedList::new(); assert_eq!(n.iter().next(), None); n.push_front(4); let mut it = n.iter(); @@ -1160,7 +1164,7 @@ mod tests { #[test] fn test_iterator_clone() { - let mut n = DList::new(); + let mut n = LinkedList::new(); n.push_back(2); n.push_back(3); n.push_back(4); @@ -1174,7 +1178,7 @@ mod tests { #[test] fn test_iterator_double_end() { - let mut n = DList::new(); + let mut n = LinkedList::new(); assert_eq!(n.iter().next(), None); n.push_front(4); n.push_front(5); @@ -1196,7 +1200,7 @@ mod tests { for (i, elt) in m.iter().rev().enumerate() { assert_eq!((6 - i) as i32, *elt); } - let mut n = DList::new(); + let mut n = LinkedList::new(); assert_eq!(n.iter().rev().next(), None); n.push_front(4); let mut it = n.iter().rev(); @@ -1215,7 +1219,7 @@ mod tests { len -= 1; } assert_eq!(len, 0); - let mut n = DList::new(); + let mut n = LinkedList::new(); assert!(n.iter_mut().next().is_none()); n.push_front(4); n.push_back(5); @@ -1229,7 +1233,7 @@ mod tests { #[test] fn test_iterator_mut_double_end() { - let mut n = DList::new(); + let mut n = LinkedList::new(); assert!(n.iter_mut().next_back().is_none()); n.push_front(4); n.push_front(5); @@ -1278,7 +1282,7 @@ mod tests { for (i, elt) in m.iter_mut().rev().enumerate() { assert_eq!((6 - i) as i32, *elt); } - let mut n = DList::new(); + let mut n = LinkedList::new(); assert!(n.iter_mut().rev().next().is_none()); n.push_front(4); let mut it = n.iter_mut().rev(); @@ -1313,8 +1317,8 @@ mod tests { #[test] fn test_hash() { - let mut x = DList::new(); - let mut y = DList::new(); + let mut x = LinkedList::new(); + let mut y = LinkedList::new(); assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y)); @@ -1382,16 +1386,16 @@ mod tests { #[test] fn test_show() { - let list: DList<_> = (0..10).collect(); - assert_eq!(format!("{:?}", list), "DList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); + let list: LinkedList<_> = (0..10).collect(); + assert_eq!(format!("{:?}", list), "LinkedList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); - let list: DList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect(); - assert_eq!(format!("{:?}", list), "DList [\"just\", \"one\", \"test\", \"more\"]"); + let list: LinkedList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect(); + assert_eq!(format!("{:?}", list), "LinkedList [\"just\", \"one\", \"test\", \"more\"]"); } #[cfg(test)] fn fuzz_test(sz: i32) { - let mut m: DList<_> = DList::new(); + let mut m: LinkedList<_> = LinkedList::new(); let mut v = vec![]; for i in 0..sz { check_links(&m); @@ -1432,13 +1436,13 @@ mod tests { fn bench_collect_into(b: &mut test::Bencher) { let v = &[0; 64]; b.iter(|| { - let _: DList<_> = v.iter().cloned().collect(); + let _: LinkedList<_> = v.iter().cloned().collect(); }) } #[bench] fn bench_push_front(b: &mut test::Bencher) { - let mut m: DList<_> = DList::new(); + let mut m: LinkedList<_> = LinkedList::new(); b.iter(|| { m.push_front(0); }) @@ -1446,7 +1450,7 @@ mod tests { #[bench] fn bench_push_back(b: &mut test::Bencher) { - let mut m: DList<_> = DList::new(); + let mut m: LinkedList<_> = LinkedList::new(); b.iter(|| { m.push_back(0); }) @@ -1454,7 +1458,7 @@ mod tests { #[bench] fn bench_push_back_pop_back(b: &mut test::Bencher) { - let mut m: DList<_> = DList::new(); + let mut m: LinkedList<_> = LinkedList::new(); b.iter(|| { m.push_back(0); m.pop_back(); @@ -1463,7 +1467,7 @@ mod tests { #[bench] fn bench_push_front_pop_front(b: &mut test::Bencher) { - let mut m: DList<_> = DList::new(); + let mut m: LinkedList<_> = LinkedList::new(); b.iter(|| { m.push_front(0); m.pop_front(); @@ -1473,7 +1477,7 @@ mod tests { #[bench] fn bench_iter(b: &mut test::Bencher) { let v = &[0; 128]; - let m: DList<_> = v.iter().cloned().collect(); + let m: LinkedList<_> = v.iter().cloned().collect(); b.iter(|| { assert!(m.iter().count() == 128); }) @@ -1481,7 +1485,7 @@ mod tests { #[bench] fn bench_iter_mut(b: &mut test::Bencher) { let v = &[0; 128]; - let mut m: DList<_> = v.iter().cloned().collect(); + let mut m: LinkedList<_> = v.iter().cloned().collect(); b.iter(|| { assert!(m.iter_mut().count() == 128); }) @@ -1489,7 +1493,7 @@ mod tests { #[bench] fn bench_iter_rev(b: &mut test::Bencher) { let v = &[0; 128]; - let m: DList<_> = v.iter().cloned().collect(); + let m: LinkedList<_> = v.iter().cloned().collect(); b.iter(|| { assert!(m.iter().rev().count() == 128); }) @@ -1497,7 +1501,7 @@ mod tests { #[bench] fn bench_iter_mut_rev(b: &mut test::Bencher) { let v = &[0; 128]; - let mut m: DList<_> = v.iter().cloned().collect(); + let mut m: LinkedList<_> = v.iter().cloned().collect(); b.iter(|| { assert!(m.iter_mut().rev().count() == 128); }) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 2d4dc2bcf30d3..94d81c74cd36a 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -68,7 +68,7 @@ use core::slice::AsSlice; use core::str as core_str; use unicode::str::{UnicodeStr, Utf16Encoder}; -use ring_buf::RingBuf; +use vec_deque::VecDeque; use slice::SliceExt; use string::String; use unicode; @@ -261,7 +261,7 @@ enum RecompositionState { pub struct Recompositions<'a> { iter: Decompositions<'a>, state: RecompositionState, - buffer: RingBuf, + buffer: VecDeque, composee: Option, last_ccc: Option } @@ -496,7 +496,7 @@ pub trait StrExt: Index { Recompositions { iter: self.nfd_chars(), state: Composing, - buffer: RingBuf::new(), + buffer: VecDeque::new(), composee: None, last_ccc: None } @@ -511,7 +511,7 @@ pub trait StrExt: Index { Recompositions { iter: self.nfkd_chars(), state: Composing, - buffer: RingBuf::new(), + buffer: VecDeque::new(), composee: None, last_ccc: None } diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/vec_deque.rs similarity index 90% rename from src/libcollections/ring_buf.rs rename to src/libcollections/vec_deque.rs index 6dcdb21f8000b..76b2d5b968ef2 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/vec_deque.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! RingBuf is a double-ended queue, which is implemented with the help of a -//! growing circular buffer. +//! VecDeque is a double-ended queue, which is implemented with the help of a +//! growing ring buffer. //! //! This queue has `O(1)` amortized inserts and removals from both ends of the //! container. It also has `O(1)` indexing like a vector. The contained elements @@ -36,12 +36,17 @@ use core::cmp; use alloc::heap; +#[deprecated(since = "1.0.0", reason = "renamed to VecDeque")] +#[unstable(feature = "collections")] +pub use VecDeque as RingBuf; + static INITIAL_CAPACITY: usize = 7; // 2^3 - 1 static MINIMUM_CAPACITY: usize = 1; // 2 - 1 -/// `RingBuf` is a circular buffer, which can be used as a double-ended queue efficiently. +/// `VecDeque` is a growable ring buffer, which can be used as a +/// double-ended queue efficiently. #[stable(feature = "rust1", since = "1.0.0")] -pub struct RingBuf { +pub struct VecDeque { // tail and head are pointers into the buffer. Tail always points // to the first element that could be read, Head always points // to where data should be written. @@ -55,21 +60,21 @@ pub struct RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Send for RingBuf {} +unsafe impl Send for VecDeque {} #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Sync for RingBuf {} +unsafe impl Sync for VecDeque {} #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for RingBuf { - fn clone(&self) -> RingBuf { +impl Clone for VecDeque { + fn clone(&self) -> VecDeque { self.iter().cloned().collect() } } #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for RingBuf { +impl Drop for VecDeque { fn drop(&mut self) { self.clear(); unsafe { @@ -83,12 +88,12 @@ impl Drop for RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for RingBuf { +impl Default for VecDeque { #[inline] - fn default() -> RingBuf { RingBuf::new() } + fn default() -> VecDeque { VecDeque::new() } } -impl RingBuf { +impl VecDeque { /// Turn ptr into a slice #[inline] unsafe fn buffer_as_slice(&self) -> &[T] { @@ -149,16 +154,16 @@ impl RingBuf { } } -impl RingBuf { - /// Creates an empty `RingBuf`. +impl VecDeque { + /// Creates an empty `VecDeque`. #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> RingBuf { - RingBuf::with_capacity(INITIAL_CAPACITY) + pub fn new() -> VecDeque { + VecDeque::with_capacity(INITIAL_CAPACITY) } - /// Creates an empty `RingBuf` with space for at least `n` elements. + /// Creates an empty `VecDeque` with space for at least `n` elements. #[stable(feature = "rust1", since = "1.0.0")] - pub fn with_capacity(n: usize) -> RingBuf { + pub fn with_capacity(n: usize) -> VecDeque { // +1 since the ringbuffer always leaves one space empty let cap = cmp::max(n + 1, MINIMUM_CAPACITY + 1).next_power_of_two(); assert!(cap > n, "capacity overflow"); @@ -175,7 +180,7 @@ impl RingBuf { heap::EMPTY as *mut T }; - RingBuf { + VecDeque { tail: 0, head: 0, cap: cap, @@ -183,14 +188,14 @@ impl RingBuf { } } - /// Retrieves an element in the `RingBuf` by index. + /// Retrieves an element in the `VecDeque` by index. /// /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(3); /// buf.push_back(4); /// buf.push_back(5); @@ -206,14 +211,14 @@ impl RingBuf { } } - /// Retrieves an element in the `RingBuf` mutably by index. + /// Retrieves an element in the `VecDeque` mutably by index. /// /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(3); /// buf.push_back(4); /// buf.push_back(5); @@ -245,9 +250,9 @@ impl RingBuf { /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(3); /// buf.push_back(4); /// buf.push_back(5); @@ -266,15 +271,15 @@ impl RingBuf { } } - /// Returns the number of elements the `RingBuf` can hold without + /// Returns the number of elements the `VecDeque` can hold without /// reallocating. /// /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let buf: RingBuf = RingBuf::with_capacity(10); + /// let buf: VecDeque = VecDeque::with_capacity(10); /// assert!(buf.capacity() >= 10); /// ``` #[inline] @@ -282,7 +287,7 @@ impl RingBuf { pub fn capacity(&self) -> usize { self.cap - 1 } /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the - /// given `RingBuf`. Does nothing if the capacity is already sufficient. + /// given `VecDeque`. Does nothing if the capacity is already sufficient. /// /// Note that the allocator may give the collection more space than it requests. Therefore /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future @@ -295,9 +300,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf: RingBuf = vec![1].into_iter().collect(); + /// let mut buf: VecDeque = vec![1].into_iter().collect(); /// buf.reserve_exact(10); /// assert!(buf.capacity() >= 11); /// ``` @@ -316,9 +321,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf: RingBuf = vec![1].into_iter().collect(); + /// let mut buf: VecDeque = vec![1].into_iter().collect(); /// buf.reserve(10); /// assert!(buf.capacity() >= 11); /// ``` @@ -390,9 +395,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::with_capacity(15); + /// let mut buf = VecDeque::with_capacity(15); /// buf.extend(0..4); /// assert_eq!(buf.capacity(), 15); /// buf.shrink_to_fit(); @@ -475,9 +480,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(5); /// buf.push_back(10); /// buf.push_back(15); @@ -498,9 +503,9 @@ impl RingBuf { /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(5); /// buf.push_back(3); /// buf.push_back(4); @@ -521,9 +526,9 @@ impl RingBuf { /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(5); /// buf.push_back(3); /// buf.push_back(4); @@ -553,7 +558,7 @@ impl RingBuf { } /// Returns a pair of slices which contain, in order, the contents of the - /// `RingBuf`. + /// `VecDeque`. #[inline] #[unstable(feature = "collections", reason = "matches collection reform specification, waiting for dust to settle")] @@ -573,7 +578,7 @@ impl RingBuf { } /// Returns a pair of slices which contain, in order, the contents of the - /// `RingBuf`. + /// `VecDeque`. #[inline] #[unstable(feature = "collections", reason = "matches collection reform specification, waiting for dust to settle")] @@ -596,14 +601,14 @@ impl RingBuf { } } - /// Returns the number of elements in the `RingBuf`. + /// Returns the number of elements in the `VecDeque`. /// /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut v = RingBuf::new(); + /// let mut v = VecDeque::new(); /// assert_eq!(v.len(), 0); /// v.push_back(1); /// assert_eq!(v.len(), 1); @@ -616,9 +621,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut v = RingBuf::new(); + /// let mut v = VecDeque::new(); /// assert!(v.is_empty()); /// v.push_front(1); /// assert!(!v.is_empty()); @@ -626,15 +631,15 @@ impl RingBuf { #[stable(feature = "rust1", since = "1.0.0")] pub fn is_empty(&self) -> bool { self.len() == 0 } - /// Creates a draining iterator that clears the `RingBuf` and iterates over + /// Creates a draining iterator that clears the `VecDeque` and iterates over /// the removed items from start to end. /// /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut v = RingBuf::new(); + /// let mut v = VecDeque::new(); /// v.push_back(1); /// assert_eq!(v.drain().next(), Some(1)); /// assert!(v.is_empty()); @@ -653,9 +658,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut v = RingBuf::new(); + /// let mut v = VecDeque::new(); /// v.push_back(1); /// v.clear(); /// assert!(v.is_empty()); @@ -672,9 +677,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut d = RingBuf::new(); + /// let mut d = VecDeque::new(); /// assert_eq!(d.front(), None); /// /// d.push_back(1); @@ -692,9 +697,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut d = RingBuf::new(); + /// let mut d = VecDeque::new(); /// assert_eq!(d.front_mut(), None); /// /// d.push_back(1); @@ -716,9 +721,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut d = RingBuf::new(); + /// let mut d = VecDeque::new(); /// assert_eq!(d.back(), None); /// /// d.push_back(1); @@ -736,9 +741,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut d = RingBuf::new(); + /// let mut d = VecDeque::new(); /// assert_eq!(d.back(), None); /// /// d.push_back(1); @@ -761,9 +766,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut d = RingBuf::new(); + /// let mut d = VecDeque::new(); /// d.push_back(1); /// d.push_back(2); /// @@ -787,9 +792,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut d = RingBuf::new(); + /// let mut d = VecDeque::new(); /// d.push_front(1); /// d.push_front(2); /// assert_eq!(d.front(), Some(&2)); @@ -811,9 +816,9 @@ impl RingBuf { /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(1); /// buf.push_back(3); /// assert_eq!(3, *buf.back().unwrap()); @@ -836,9 +841,9 @@ impl RingBuf { /// # Examples /// /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// assert_eq!(buf.pop_back(), None); /// buf.push_back(1); /// buf.push_back(3); @@ -870,9 +875,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// assert_eq!(buf.swap_back_remove(0), None); /// buf.push_back(5); /// buf.push_back(99); @@ -903,9 +908,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// assert_eq!(buf.swap_front_remove(0), None); /// buf.push_back(15); /// buf.push_back(5); @@ -936,9 +941,9 @@ impl RingBuf { /// /// # Examples /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(10); /// buf.push_back(12); /// buf.insert(1,11); @@ -1138,9 +1143,9 @@ impl RingBuf { /// /// # Examples /// ```rust - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(5); /// buf.push_back(10); /// buf.push_back(12); @@ -1309,9 +1314,9 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf: RingBuf<_> = vec![1,2,3].into_iter().collect(); + /// let mut buf: VecDeque<_> = vec![1,2,3].into_iter().collect(); /// let buf2 = buf.split_off(1); /// // buf = [1], buf2 = [2, 3] /// assert_eq!(buf.len(), 1); @@ -1325,7 +1330,7 @@ impl RingBuf { assert!(at <= len, "`at` out of bounds"); let other_len = len - at; - let mut other = RingBuf::with_capacity(other_len); + let mut other = VecDeque::with_capacity(other_len); unsafe { let (first_half, second_half) = self.as_slices(); @@ -1371,10 +1376,10 @@ impl RingBuf { /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf: RingBuf<_> = vec![1, 2, 3].into_iter().collect(); - /// let mut buf2: RingBuf<_> = vec![4, 5, 6].into_iter().collect(); + /// let mut buf: VecDeque<_> = vec![1, 2, 3].into_iter().collect(); + /// let mut buf2: VecDeque<_> = vec![4, 5, 6].into_iter().collect(); /// buf.append(&mut buf2); /// assert_eq!(buf.len(), 6); /// assert_eq!(buf2.len(), 0); @@ -1388,16 +1393,16 @@ impl RingBuf { } } -impl RingBuf { +impl VecDeque { /// Modifies the ringbuf in-place so that `len()` is equal to new_len, /// either by removing excess elements or by appending copies of a value to the back. /// /// # Examples /// /// ``` - /// use std::collections::RingBuf; + /// use std::collections::VecDeque; /// - /// let mut buf = RingBuf::new(); + /// let mut buf = VecDeque::new(); /// buf.push_back(5); /// buf.push_back(10); /// buf.push_back(15); @@ -1434,7 +1439,7 @@ fn count(tail: usize, head: usize, size: usize) -> usize { (head - tail) & (size - 1) } -/// `RingBuf` iterator. +/// `VecDeque` iterator. #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, T:'a> { ring: &'a [T], @@ -1511,7 +1516,7 @@ impl<'a, T> RandomAccessIterator for Iter<'a, T> { // FIXME This was implemented differently from Iter because of a problem // with returning the mutable reference. I couldn't find a way to // make the lifetime checker happy so, but there should be a way. -/// `RingBuf` mutable iterator. +/// `VecDeque` mutable iterator. #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, T:'a> { ptr: *mut T, @@ -1563,10 +1568,10 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> ExactSizeIterator for IterMut<'a, T> {} -/// A by-value RingBuf iterator +/// A by-value VecDeque iterator #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { - inner: RingBuf, + inner: VecDeque, } #[stable(feature = "rust1", since = "1.0.0")] @@ -1596,11 +1601,11 @@ impl DoubleEndedIterator for IntoIter { #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for IntoIter {} -/// A draining RingBuf iterator +/// A draining VecDeque iterator #[unstable(feature = "collections", reason = "matches collection reform specification, waiting for dust to settle")] pub struct Drain<'a, T: 'a> { - inner: &'a mut RingBuf, + inner: &'a mut VecDeque, } #[unsafe_destructor] @@ -1641,33 +1646,33 @@ impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> { impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {} #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for RingBuf { - fn eq(&self, other: &RingBuf) -> bool { +impl PartialEq for VecDeque { + fn eq(&self, other: &VecDeque) -> bool { self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| a.eq(b)) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for RingBuf {} +impl Eq for VecDeque {} #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for RingBuf { - fn partial_cmp(&self, other: &RingBuf) -> Option { +impl PartialOrd for VecDeque { + fn partial_cmp(&self, other: &VecDeque) -> Option { iter::order::partial_cmp(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for RingBuf { +impl Ord for VecDeque { #[inline] - fn cmp(&self, other: &RingBuf) -> Ordering { + fn cmp(&self, other: &VecDeque) -> Ordering { iter::order::cmp(self.iter(), other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl> Hash for RingBuf { +impl> Hash for VecDeque { fn hash(&self, state: &mut S) { self.len().hash(state); for elt in self { @@ -1677,7 +1682,7 @@ impl> Hash for RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl Index for RingBuf { +impl Index for VecDeque { type Output = A; #[inline] @@ -1687,7 +1692,7 @@ impl Index for RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl IndexMut for RingBuf { +impl IndexMut for VecDeque { #[inline] fn index_mut(&mut self, i: &usize) -> &mut A { self.get_mut(*i).expect("Out of bounds access") @@ -1695,17 +1700,17 @@ impl IndexMut for RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl FromIterator for RingBuf { - fn from_iter>(iterator: T) -> RingBuf { +impl FromIterator for VecDeque { + fn from_iter>(iterator: T) -> VecDeque { let (lower, _) = iterator.size_hint(); - let mut deq = RingBuf::with_capacity(lower); + let mut deq = VecDeque::with_capacity(lower); deq.extend(iterator); deq } } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for RingBuf { +impl IntoIterator for VecDeque { type Item = T; type IntoIter = IntoIter; @@ -1715,7 +1720,7 @@ impl IntoIterator for RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a RingBuf { +impl<'a, T> IntoIterator for &'a VecDeque { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -1725,7 +1730,7 @@ impl<'a, T> IntoIterator for &'a RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a mut RingBuf { +impl<'a, T> IntoIterator for &'a mut VecDeque { type Item = &'a mut T; type IntoIter = IterMut<'a, T>; @@ -1735,7 +1740,7 @@ impl<'a, T> IntoIterator for &'a mut RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for RingBuf { +impl Extend for VecDeque { fn extend>(&mut self, iterator: T) { for elt in iterator { self.push_back(elt); @@ -1744,9 +1749,9 @@ impl Extend for RingBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for RingBuf { +impl fmt::Debug for VecDeque { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "RingBuf [")); + try!(write!(f, "VecDeque [")); for (i, e) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -1768,12 +1773,12 @@ mod tests { use test::Bencher; use test; - use super::RingBuf; + use super::VecDeque; #[test] #[allow(deprecated)] fn test_simple() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); assert_eq!(d.len(), 0); d.push_front(17); d.push_front(42); @@ -1812,7 +1817,7 @@ mod tests { #[cfg(test)] fn test_parameterized(a: T, b: T, c: T, d: T) { - let mut deq = RingBuf::new(); + let mut deq = VecDeque::new(); assert_eq!(deq.len(), 0); deq.push_front(a.clone()); deq.push_front(b.clone()); @@ -1843,7 +1848,7 @@ mod tests { #[test] fn test_push_front_grow() { - let mut deq = RingBuf::new(); + let mut deq = VecDeque::new(); for i in 0..66 { deq.push_front(i); } @@ -1853,7 +1858,7 @@ mod tests { assert_eq!(deq[i], 65 - i); } - let mut deq = RingBuf::new(); + let mut deq = VecDeque::new(); for i in 0..66 { deq.push_back(i); } @@ -1865,7 +1870,7 @@ mod tests { #[test] fn test_index() { - let mut deq = RingBuf::new(); + let mut deq = VecDeque::new(); for i in 1..4 { deq.push_front(i); } @@ -1875,7 +1880,7 @@ mod tests { #[test] #[should_fail] fn test_index_out_of_bounds() { - let mut deq = RingBuf::new(); + let mut deq = VecDeque::new(); for i in 1..4 { deq.push_front(i); } @@ -1885,14 +1890,14 @@ mod tests { #[bench] fn bench_new(b: &mut test::Bencher) { b.iter(|| { - let ring: RingBuf = RingBuf::new(); + let ring: VecDeque = VecDeque::new(); test::black_box(ring); }) } #[bench] fn bench_push_back_100(b: &mut test::Bencher) { - let mut deq = RingBuf::with_capacity(101); + let mut deq = VecDeque::with_capacity(101); b.iter(|| { for i in 0..100 { deq.push_back(i); @@ -1904,7 +1909,7 @@ mod tests { #[bench] fn bench_push_front_100(b: &mut test::Bencher) { - let mut deq = RingBuf::with_capacity(101); + let mut deq = VecDeque::with_capacity(101); b.iter(|| { for i in 0..100 { deq.push_front(i); @@ -1916,7 +1921,7 @@ mod tests { #[bench] fn bench_pop_back_100(b: &mut test::Bencher) { - let mut deq= RingBuf::::with_capacity(101); + let mut deq= VecDeque::::with_capacity(101); b.iter(|| { deq.head = 100; @@ -1929,7 +1934,7 @@ mod tests { #[bench] fn bench_pop_front_100(b: &mut test::Bencher) { - let mut deq = RingBuf::::with_capacity(101); + let mut deq = VecDeque::::with_capacity(101); b.iter(|| { deq.head = 100; @@ -1943,7 +1948,7 @@ mod tests { #[bench] fn bench_grow_1025(b: &mut test::Bencher) { b.iter(|| { - let mut deq = RingBuf::new(); + let mut deq = VecDeque::new(); for i in 0..1025 { deq.push_front(i); } @@ -1953,7 +1958,7 @@ mod tests { #[bench] fn bench_iter_1000(b: &mut test::Bencher) { - let ring: RingBuf<_> = (0..1000).collect(); + let ring: VecDeque<_> = (0..1000).collect(); b.iter(|| { let mut sum = 0; @@ -1966,7 +1971,7 @@ mod tests { #[bench] fn bench_mut_iter_1000(b: &mut test::Bencher) { - let mut ring: RingBuf<_> = (0..1000).collect(); + let mut ring: VecDeque<_> = (0..1000).collect(); b.iter(|| { let mut sum = 0; @@ -2027,17 +2032,17 @@ mod tests { #[test] fn test_with_capacity() { - let mut d = RingBuf::with_capacity(0); + let mut d = VecDeque::with_capacity(0); d.push_back(1); assert_eq!(d.len(), 1); - let mut d = RingBuf::with_capacity(50); + let mut d = VecDeque::with_capacity(50); d.push_back(1); assert_eq!(d.len(), 1); } #[test] fn test_with_capacity_non_power_two() { - let mut d3 = RingBuf::with_capacity(3); + let mut d3 = VecDeque::with_capacity(3); d3.push_back(1); // X = None, | = lo @@ -2062,7 +2067,7 @@ mod tests { d3.push_back(15); // There used to be a bug here about how the - // RingBuf made growth assumptions about the + // VecDeque made growth assumptions about the // underlying Vec which didn't hold and lead // to corruption. // (Vec grows to next power of two) @@ -2078,7 +2083,7 @@ mod tests { #[test] fn test_reserve_exact() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); d.push_back(0); d.reserve_exact(50); assert!(d.capacity() >= 51); @@ -2086,7 +2091,7 @@ mod tests { #[test] fn test_reserve() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); d.push_back(0); d.reserve(50); assert!(d.capacity() >= 51); @@ -2094,7 +2099,7 @@ mod tests { #[test] fn test_swap() { - let mut d: RingBuf<_> = (0..5).collect(); + let mut d: VecDeque<_> = (0..5).collect(); d.pop_front(); d.swap(0, 3); assert_eq!(d.iter().cloned().collect::>(), vec!(4, 2, 3, 1)); @@ -2102,7 +2107,7 @@ mod tests { #[test] fn test_iter() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); assert_eq!(d.iter().next(), None); assert_eq!(d.iter().size_hint(), (0, Some(0))); @@ -2134,7 +2139,7 @@ mod tests { #[test] fn test_rev_iter() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); assert_eq!(d.iter().rev().next(), None); for i in 0..5 { @@ -2154,7 +2159,7 @@ mod tests { #[test] fn test_mut_rev_iter_wrap() { - let mut d = RingBuf::with_capacity(3); + let mut d = VecDeque::with_capacity(3); assert!(d.iter_mut().rev().next().is_none()); d.push_back(1); @@ -2169,7 +2174,7 @@ mod tests { #[test] fn test_mut_iter() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); assert!(d.iter_mut().next().is_none()); for i in 0..3 { @@ -2192,7 +2197,7 @@ mod tests { #[test] fn test_mut_rev_iter() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); assert!(d.iter_mut().rev().next().is_none()); for i in 0..3 { @@ -2218,7 +2223,7 @@ mod tests { // Empty iter { - let d: RingBuf = RingBuf::new(); + let d: VecDeque = VecDeque::new(); let mut iter = d.into_iter(); assert_eq!(iter.size_hint(), (0, Some(0))); @@ -2228,7 +2233,7 @@ mod tests { // simple iter { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); for i in 0..5 { d.push_back(i); } @@ -2239,7 +2244,7 @@ mod tests { // wrapped iter { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); for i in 0..5 { d.push_back(i); } @@ -2253,7 +2258,7 @@ mod tests { // partially used { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); for i in 0..5 { d.push_back(i); } @@ -2277,7 +2282,7 @@ mod tests { // Empty iter { - let mut d: RingBuf = RingBuf::new(); + let mut d: VecDeque = VecDeque::new(); { let mut iter = d.drain(); @@ -2292,7 +2297,7 @@ mod tests { // simple iter { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); for i in 0..5 { d.push_back(i); } @@ -2303,7 +2308,7 @@ mod tests { // wrapped iter { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); for i in 0..5 { d.push_back(i); } @@ -2317,7 +2322,7 @@ mod tests { // partially used { - let mut d: RingBuf<_> = RingBuf::new(); + let mut d: VecDeque<_> = VecDeque::new(); for i in 0..5 { d.push_back(i); } @@ -2343,12 +2348,12 @@ mod tests { fn test_from_iter() { use core::iter; let v = vec!(1,2,3,4,5,6,7); - let deq: RingBuf<_> = v.iter().cloned().collect(); + let deq: VecDeque<_> = v.iter().cloned().collect(); let u: Vec<_> = deq.iter().cloned().collect(); assert_eq!(u, v); let seq = iter::count(0, 2).take(256); - let deq: RingBuf<_> = seq.collect(); + let deq: VecDeque<_> = seq.collect(); for (i, &x) in deq.iter().enumerate() { assert_eq!(2*i, x); } @@ -2357,7 +2362,7 @@ mod tests { #[test] fn test_clone() { - let mut d = RingBuf::new(); + let mut d = VecDeque::new(); d.push_front(17); d.push_front(42); d.push_back(137); @@ -2374,13 +2379,13 @@ mod tests { #[test] fn test_eq() { - let mut d = RingBuf::new(); - assert!(d == RingBuf::with_capacity(0)); + let mut d = VecDeque::new(); + assert!(d == VecDeque::with_capacity(0)); d.push_front(137); d.push_front(17); d.push_front(42); d.push_back(137); - let mut e = RingBuf::with_capacity(0); + let mut e = VecDeque::with_capacity(0); e.push_back(42); e.push_back(17); e.push_back(137); @@ -2390,13 +2395,13 @@ mod tests { e.push_back(0); assert!(e != d); e.clear(); - assert!(e == RingBuf::new()); + assert!(e == VecDeque::new()); } #[test] fn test_hash() { - let mut x = RingBuf::new(); - let mut y = RingBuf::new(); + let mut x = VecDeque::new(); + let mut y = VecDeque::new(); x.push_back(1); x.push_back(2); @@ -2413,8 +2418,8 @@ mod tests { #[test] fn test_ord() { - let x = RingBuf::new(); - let mut y = RingBuf::new(); + let x = VecDeque::new(); + let mut y = VecDeque::new(); y.push_back(1); y.push_back(2); y.push_back(3); @@ -2426,13 +2431,13 @@ mod tests { #[test] fn test_show() { - let ringbuf: RingBuf<_> = (0..10).collect(); - assert_eq!(format!("{:?}", ringbuf), "RingBuf [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); + let ringbuf: VecDeque<_> = (0..10).collect(); + assert_eq!(format!("{:?}", ringbuf), "VecDeque [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); - let ringbuf: RingBuf<_> = vec!["just", "one", "test", "more"].iter() + let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"].iter() .cloned() .collect(); - assert_eq!(format!("{:?}", ringbuf), "RingBuf [\"just\", \"one\", \"test\", \"more\"]"); + assert_eq!(format!("{:?}", ringbuf), "VecDeque [\"just\", \"one\", \"test\", \"more\"]"); } #[test] @@ -2445,7 +2450,7 @@ mod tests { } } - let mut ring = RingBuf::new(); + let mut ring = VecDeque::new(); ring.push_back(Elem); ring.push_front(Elem); ring.push_back(Elem); @@ -2465,7 +2470,7 @@ mod tests { } } - let mut ring = RingBuf::new(); + let mut ring = VecDeque::new(); ring.push_back(Elem); ring.push_front(Elem); ring.push_back(Elem); @@ -2489,7 +2494,7 @@ mod tests { } } - let mut ring = RingBuf::new(); + let mut ring = VecDeque::new(); ring.push_back(Elem); ring.push_front(Elem); ring.push_back(Elem); @@ -2505,7 +2510,7 @@ mod tests { fn test_reserve_grow() { // test growth path A // [T o o H] -> [T o o H . . . . ] - let mut ring = RingBuf::with_capacity(4); + let mut ring = VecDeque::with_capacity(4); for i in 0..3 { ring.push_back(i); } @@ -2516,7 +2521,7 @@ mod tests { // test growth path B // [H T o o] -> [. T o o H . . . ] - let mut ring = RingBuf::with_capacity(4); + let mut ring = VecDeque::with_capacity(4); for i in 0..1 { ring.push_back(i); assert_eq!(ring.pop_front(), Some(i)); @@ -2531,7 +2536,7 @@ mod tests { // test growth path C // [o o H T] -> [o o H . . . . T ] - let mut ring = RingBuf::with_capacity(4); + let mut ring = VecDeque::with_capacity(4); for i in 0..3 { ring.push_back(i); assert_eq!(ring.pop_front(), Some(i)); @@ -2547,7 +2552,7 @@ mod tests { #[test] fn test_get() { - let mut ring = RingBuf::new(); + let mut ring = VecDeque::new(); ring.push_back(0); assert_eq!(ring.get(0), Some(&0)); assert_eq!(ring.get(1), None); @@ -2579,7 +2584,7 @@ mod tests { #[test] fn test_get_mut() { - let mut ring = RingBuf::new(); + let mut ring = VecDeque::new(); for i in 0..3 { ring.push_back(i); } @@ -2605,7 +2610,7 @@ mod tests { fn test(back: bool) { // This test checks that every single combination of tail position and length is tested. // Capacity 15 should be large enough to cover every case. - let mut tester = RingBuf::with_capacity(15); + let mut tester = VecDeque::with_capacity(15); let usable_cap = tester.capacity(); let final_len = usable_cap / 2; @@ -2649,7 +2654,7 @@ mod tests { // This test checks that every single combination of tail position, length, and // insertion position is tested. Capacity 15 should be large enough to cover every case. - let mut tester = RingBuf::with_capacity(15); + let mut tester = VecDeque::with_capacity(15); // can't guarantee we got 15, so have to get what we got. // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else // this test isn't covering what it wants to @@ -2683,7 +2688,7 @@ mod tests { // This test checks that every single combination of tail position, length, and // removal position is tested. Capacity 15 should be large enough to cover every case. - let mut tester = RingBuf::with_capacity(15); + let mut tester = VecDeque::with_capacity(15); // can't guarantee we got 15, so have to get what we got. // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else // this test isn't covering what it wants to @@ -2720,7 +2725,7 @@ mod tests { // This test checks that every single combination of head and tail position, // is tested. Capacity 15 should be large enough to cover every case. - let mut tester = RingBuf::with_capacity(15); + let mut tester = VecDeque::with_capacity(15); // can't guarantee we got 15, so have to get what we got. // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else // this test isn't covering what it wants to @@ -2749,7 +2754,7 @@ mod tests { #[test] fn test_front() { - let mut ring = RingBuf::new(); + let mut ring = VecDeque::new(); ring.push_back(10); ring.push_back(20); assert_eq!(ring.front(), Some(&10)); @@ -2761,7 +2766,7 @@ mod tests { #[test] fn test_as_slices() { - let mut ring: RingBuf = RingBuf::with_capacity(127); + let mut ring: VecDeque = VecDeque::with_capacity(127); let cap = ring.capacity() as i32; let first = cap/2; let last = cap - first; @@ -2789,7 +2794,7 @@ mod tests { #[test] fn test_as_mut_slices() { - let mut ring: RingBuf = RingBuf::with_capacity(127); + let mut ring: VecDeque = VecDeque::with_capacity(127); let cap = ring.capacity() as i32; let first = cap/2; let last = cap - first; @@ -2820,7 +2825,7 @@ mod tests { // This test checks that every single combination of tail position, length, and // split position is tested. Capacity 15 should be large enough to cover every case. - let mut tester = RingBuf::with_capacity(15); + let mut tester = VecDeque::with_capacity(15); // can't guarantee we got 15, so have to get what we got. // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else // this test isn't covering what it wants to @@ -2855,8 +2860,8 @@ mod tests { #[test] fn test_append() { - let mut a: RingBuf<_> = vec![1, 2, 3].into_iter().collect(); - let mut b: RingBuf<_> = vec![4, 5, 6].into_iter().collect(); + let mut a: VecDeque<_> = vec![1, 2, 3].into_iter().collect(); + let mut b: VecDeque<_> = vec![4, 5, 6].into_iter().collect(); // normal append a.append(&mut b); diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index ba108b5488ede..582cd4f384f31 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -37,7 +37,7 @@ use util::ppaux::{ty_to_string}; use util::nodemap::{FnvHashMap, NodeSet}; use lint::{Level, Context, LintPass, LintArray, Lint}; -use std::collections::BitvSet; +use std::collections::BitSet; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::num::SignedInt; use std::{cmp, slice}; @@ -1792,7 +1792,7 @@ impl LintPass for UnconditionalRecursion { let mut work_queue = vec![cfg.entry]; let mut reached_exit_without_self_call = false; let mut self_call_spans = vec![]; - let mut visited = BitvSet::new(); + let mut visited = BitSet::new(); while let Some(idx) = work_queue.pop() { let cfg_id = idx.node_id(); diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs index 4dd7a4a226629..436f04fc9e9cf 100644 --- a/src/librustc/middle/graph.rs +++ b/src/librustc/middle/graph.rs @@ -34,7 +34,7 @@ use std::fmt::{Formatter, Error, Debug}; use std::usize; -use std::collections::BitvSet; +use std::collections::BitSet; pub struct Graph { nodes: Vec> , @@ -292,7 +292,7 @@ impl Graph { DepthFirstTraversal { graph: self, stack: vec![start], - visited: BitvSet::new() + visited: BitSet::new() } } } @@ -300,7 +300,7 @@ impl Graph { pub struct DepthFirstTraversal<'g, N:'g, E:'g> { graph: &'g Graph, stack: Vec, - visited: BitvSet + visited: BitSet } impl<'g, N, E> Iterator for DepthFirstTraversal<'g, N, E> { diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs index f81edca837198..ac56cc3750658 100644 --- a/src/libserialize/collection_impls.rs +++ b/src/libserialize/collection_impls.rs @@ -16,12 +16,12 @@ use std::hash::{Hash, Hasher}; use std::collections::hash_state::HashState; use {Decodable, Encodable, Decoder, Encoder}; -use std::collections::{DList, RingBuf, BTreeMap, BTreeSet, HashMap, HashSet, VecMap}; +use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet, VecMap}; use collections::enum_set::{EnumSet, CLike}; impl< T: Encodable -> Encodable for DList { +> Encodable for LinkedList { fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_seq(self.len(), |s| { for (i, e) in self.iter().enumerate() { @@ -32,10 +32,10 @@ impl< } } -impl Decodable for DList { - fn decode(d: &mut D) -> Result, D::Error> { +impl Decodable for LinkedList { + fn decode(d: &mut D) -> Result, D::Error> { d.read_seq(|d, len| { - let mut list = DList::new(); + let mut list = LinkedList::new(); for i in 0..len { list.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); } @@ -44,7 +44,7 @@ impl Decodable for DList { } } -impl Encodable for RingBuf { +impl Encodable for VecDeque { fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_seq(self.len(), |s| { for (i, e) in self.iter().enumerate() { @@ -55,10 +55,10 @@ impl Encodable for RingBuf { } } -impl Decodable for RingBuf { - fn decode(d: &mut D) -> Result, D::Error> { +impl Decodable for VecDeque { + fn decode(d: &mut D) -> Result, D::Error> { d.read_seq(|d, len| { - let mut deque: RingBuf = RingBuf::new(); + let mut deque: VecDeque = VecDeque::new(); for i in 0..len { deque.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); } diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index be441bfec8865..0e64370df60ec 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -23,7 +23,7 @@ //! //! Rust's collections can be grouped into four major categories: //! -//! * Sequences: `Vec`, `RingBuf`, `DList`, `BitV` +//! * Sequences: `Vec`, `VecDeque`, `LinkedList`, `BitV` //! * Maps: `HashMap`, `BTreeMap`, `VecMap` //! * Sets: `HashSet`, `BTreeSet`, `BitVSet` //! * Misc: `BinaryHeap` @@ -43,13 +43,13 @@ //! * You want a resizable array. //! * You want a heap-allocated array. //! -//! ### Use a `RingBuf` when: +//! ### Use a `VecDeque` when: //! * You want a `Vec` that supports efficient insertion at both ends of the sequence. //! * You want a queue. //! * You want a double-ended queue (deque). //! -//! ### Use a `DList` when: -//! * You want a `Vec` or `RingBuf` of unknown size, and can't tolerate amortization. +//! ### Use a `LinkedList` when: +//! * You want a `Vec` or `VecDeque` of unknown size, and can't tolerate amortization. //! * You want to efficiently split and append lists. //! * You are *absolutely* certain you *really*, *truly*, want a doubly linked list. //! @@ -75,7 +75,7 @@ //! //! ### Use a `BitV` when: //! * You want to store an unbounded number of booleans in a small space. -//! * You want a bitvector. +//! * You want a bit vector. //! //! ### Use a `BitVSet` when: //! * You want a `VecSet`. @@ -106,20 +106,20 @@ //! //! ## Sequences //! -//! | | get(i) | insert(i) | remove(i) | append | split_off(i) | -//! |---------|----------------|-----------------|----------------|--------|----------------| -//! | Vec | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | -//! | RingBuf | O(1) | O(min(i, n-i))* | O(min(i, n-i)) | O(m)* | O(min(i, n-i)) | -//! | DList | O(min(i, n-i)) | O(min(i, n-i)) | O(min(i, n-i)) | O(1) | O(min(i, n-i)) | -//! | Bitv | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | +//! | | get(i) | insert(i) | remove(i) | append | split_off(i) | +//! |--------------|----------------|-----------------|----------------|--------|----------------| +//! | Vec | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | +//! | VecDeque | O(1) | O(min(i, n-i))* | O(min(i, n-i)) | O(m)* | O(min(i, n-i)) | +//! | LinkedList | O(min(i, n-i)) | O(min(i, n-i)) | O(min(i, n-i)) | O(1) | O(min(i, n-i)) | +//! | BitVec | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) | //! -//! Note that where ties occur, Vec is generally going to be faster than RingBuf, and RingBuf -//! is generally going to be faster than DList. Bitv is not a general purpose collection, and +//! Note that where ties occur, Vec is generally going to be faster than VecDeque, and VecDeque +//! is generally going to be faster than LinkedList. BitVec is not a general purpose collection, and //! therefore cannot reasonably be compared. //! //! ## Maps //! -//! For Sets, all operations have the cost of the equivalent Map operation. For BitvSet, +//! For Sets, all operations have the cost of the equivalent Map operation. For BitSet, //! refer to VecMap. //! //! | | get | insert | remove | predecessor | @@ -166,7 +166,7 @@ //! //! Any `with_capacity` constructor will instruct the collection to allocate enough space //! for the specified number of elements. Ideally this will be for exactly that many -//! elements, but some implementation details may prevent this. `Vec` and `RingBuf` can +//! elements, but some implementation details may prevent this. `Vec` and `VecDeque` can //! be relied on to allocate exactly the requested amount, though. Use `with_capacity` //! when you know exactly how many elements will be inserted, or at least have a //! reasonable upper-bound on that number. @@ -240,10 +240,10 @@ //! ``` //! //! ``` -//! use std::collections::RingBuf; +//! use std::collections::VecDeque; //! //! let vec = vec![1, 2, 3, 4]; -//! let buf: RingBuf<_> = vec.into_iter().collect(); +//! let buf: VecDeque<_> = vec.into_iter().collect(); //! ``` //! //! Iterators also provide a series of *adapter* methods for performing common tasks to @@ -362,11 +362,11 @@ #![stable(feature = "rust1", since = "1.0.0")] pub use core_collections::Bound; -pub use core_collections::{BinaryHeap, Bitv, BitvSet, BTreeMap, BTreeSet}; -pub use core_collections::{DList, RingBuf, VecMap}; +pub use core_collections::{BinaryHeap, BitVec, BitSet, BTreeMap, BTreeSet}; +pub use core_collections::{LinkedList, VecDeque, VecMap}; -pub use core_collections::{binary_heap, bitv, bitv_set, btree_map, btree_set}; -pub use core_collections::{dlist, ring_buf, vec_map}; +pub use core_collections::{binary_heap, bit_vec, bit_set, btree_map, btree_set}; +pub use core_collections::{linked_list, vec_deque, vec_map}; pub use self::hash_map::HashMap; pub use self::hash_set::HashSet; diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index a3afe5780d0d5..56efa5e0c935d 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -26,11 +26,11 @@ use parse::token; use ptr::P; use std::cell::{RefCell, Cell}; -use std::collections::BitvSet; +use std::collections::BitSet; use std::collections::HashSet; use std::fmt; -thread_local! { static USED_ATTRS: RefCell = RefCell::new(BitvSet::new()) } +thread_local! { static USED_ATTRS: RefCell = RefCell::new(BitSet::new()) } pub fn mark_used(attr: &Attribute) { let AttrId(id) = attr.node.id; diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index 1d440c4540ca3..8bddd655e23c3 100644 --- a/src/test/bench/core-set.rs +++ b/src/test/bench/core-set.rs @@ -16,7 +16,7 @@ extern crate collections; extern crate rand; use std::collections::BTreeSet; -use std::collections::BitvSet; +use std::collections::BitSet; use std::collections::HashSet; use std::collections::hash_map::Hasher; use std::hash::Hash; @@ -53,7 +53,7 @@ impl MutableSet for BTreeSet { fn remove(&mut self, k: &T) -> bool { self.remove(k) } fn contains(&self, k: &T) -> bool { self.contains(k) } } -impl MutableSet for BitvSet { +impl MutableSet for BitSet { fn insert(&mut self, k: usize) { self.insert(k); } fn remove(&mut self, k: &usize) -> bool { self.remove(k) } fn contains(&self, k: &usize) -> bool { self.contains(k) } @@ -222,7 +222,7 @@ fn main() { { let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed); let mut results = empty_results(); - results.bench_int(&mut rng, num_keys, max, || BitvSet::new()); - write_results("collections::bitv::BitvSet", &results); + results.bench_int(&mut rng, num_keys, max, || BitSet::new()); + write_results("collections::bit_vec::BitSet", &results); } } From 4a9d190423f67a00053f4b5c9869f0ccbdfcc689 Mon Sep 17 00:00:00 2001 From: Alexis Date: Wed, 18 Feb 2015 10:04:30 -0500 Subject: [PATCH 47/76] make Extend use IntoIterator This breaks all implementors of Extend, as they must now accept IntoIterator instead of Iterator. The fix for this is generally trivial (change the bound, and maybe call into_iter() on the argument to get the old argument). Users of Extend should be unaffected because Iterators are IntoIterator. [breaking-change] --- src/libcollections/binary_heap.rs | 3 ++- src/libcollections/bit.rs | 7 ++++--- src/libcollections/btree/map.rs | 2 +- src/libcollections/btree/set.rs | 2 +- src/libcollections/enum_set.rs | 4 ++-- src/libcollections/linked_list.rs | 4 ++-- src/libcollections/string.rs | 8 +++++--- src/libcollections/vec.rs | 3 ++- src/libcollections/vec_deque.rs | 4 ++-- src/libcollections/vec_map.rs | 2 +- src/libcore/iter.rs | 2 +- src/libstd/collections/hash/map.rs | 2 +- src/libstd/collections/hash/set.rs | 2 +- src/libstd/path.rs | 4 ++-- src/libstd/sys/common/wtf8.rs | 5 +++-- src/libsyntax/util/small_vector.rs | 4 ++-- 16 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index 6196d94b5a6bd..2f994e94ccc3e 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -677,7 +677,8 @@ impl<'a, T> IntoIterator for &'a BinaryHeap where T: Ord { #[stable(feature = "rust1", since = "1.0.0")] impl Extend for BinaryHeap { - fn extend>(&mut self, iter: Iter) { + fn extend>(&mut self, iterable: I) { + let iter = iterable.into_iter(); let (lower, _) = iter.size_hint(); self.reserve(lower); diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index a2e36155933c9..c1d79d8204384 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -934,7 +934,8 @@ impl FromIterator for BitVec { #[stable(feature = "rust1", since = "1.0.0")] impl Extend for BitVec { #[inline] - fn extend>(&mut self, iterator: I) { + fn extend>(&mut self, iterable: I) { + let iterator = iterable.into_iter(); let (min, _) = iterator.size_hint(); self.reserve(min); for element in iterator { @@ -1143,8 +1144,8 @@ impl FromIterator for BitSet { #[stable(feature = "rust1", since = "1.0.0")] impl Extend for BitSet { #[inline] - fn extend>(&mut self, iterator: I) { - for i in iterator { + fn extend>(&mut self, iter: I) { + for i in iter { self.insert(i); } } diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 96052156df03e..9273d50db856b 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -836,7 +836,7 @@ impl FromIterator<(K, V)> for BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] impl Extend<(K, V)> for BTreeMap { #[inline] - fn extend>(&mut self, iter: T) { + fn extend>(&mut self, iter: T) { for (k, v) in iter { self.insert(k, v); } diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 7ef887b70cc6c..d2241a6746499 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -503,7 +503,7 @@ impl<'a, T> IntoIterator for &'a BTreeSet { #[stable(feature = "rust1", since = "1.0.0")] impl Extend for BTreeSet { #[inline] - fn extend>(&mut self, iter: Iter) { + fn extend>(&mut self, iter: Iter) { for elem in iter { self.insert(elem); } diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index d5403ca5d9b19..3f8c0121fafb5 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -268,8 +268,8 @@ impl<'a, E> IntoIterator for &'a EnumSet where E: CLike { } impl Extend for EnumSet { - fn extend>(&mut self, iterator: I) { - for element in iterator { + fn extend>(&mut self, iter: I) { + for element in iter { self.insert(element); } } diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 550c1450b93af..0ec1371c73cbf 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -872,8 +872,8 @@ impl<'a, T> IntoIterator for &'a mut LinkedList { #[stable(feature = "rust1", since = "1.0.0")] impl Extend for LinkedList { - fn extend>(&mut self, iterator: T) { - for elt in iterator { self.push_back(elt); } + fn extend>(&mut self, iter: T) { + for elt in iter { self.push_back(elt); } } } diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 69fd28d172368..dc1158ecaf85e 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -21,7 +21,7 @@ use core::default::Default; use core::error::Error; use core::fmt; use core::hash; -use core::iter::FromIterator; +use core::iter::{IntoIterator, FromIterator}; use core::mem; use core::ops::{self, Deref, Add, Index}; use core::ptr; @@ -728,7 +728,8 @@ impl<'a> FromIterator<&'a str> for String { #[unstable(feature = "collections", reason = "waiting on Extend stabilization")] impl Extend for String { - fn extend>(&mut self, iterator: I) { + fn extend>(&mut self, iterable: I) { + let iterator = iterable.into_iter(); let (lower_bound, _) = iterator.size_hint(); self.reserve(lower_bound); for ch in iterator { @@ -740,7 +741,8 @@ impl Extend for String { #[unstable(feature = "collections", reason = "waiting on Extend stabilization")] impl<'a> Extend<&'a str> for String { - fn extend>(&mut self, iterator: I) { + fn extend>(&mut self, iterable: I) { + let iterator = iterable.into_iter(); // A guess that at least one byte per iterator element will be needed. let (lower_bound, _) = iterator.size_hint(); self.reserve(lower_bound); diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index bde733644b5b5..e4b090e4dd7ac 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1480,7 +1480,8 @@ impl<'a, T> IntoIterator for &'a mut Vec { #[unstable(feature = "collections", reason = "waiting on Extend stability")] impl Extend for Vec { #[inline] - fn extend>(&mut self, iterator: I) { + fn extend>(&mut self, iterable: I) { + let iterator = iterable.into_iter(); let (lower, _) = iterator.size_hint(); self.reserve(lower); for element in iterator { diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index 76b2d5b968ef2..cc01e800f6073 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -1741,8 +1741,8 @@ impl<'a, T> IntoIterator for &'a mut VecDeque { #[stable(feature = "rust1", since = "1.0.0")] impl Extend for VecDeque { - fn extend>(&mut self, iterator: T) { - for elt in iterator { + fn extend>(&mut self, iter: T) { + for elt in iter { self.push_back(elt); } } diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 82ccfd0614fd5..7085111d6a87b 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -700,7 +700,7 @@ impl<'a, T> IntoIterator for &'a mut VecMap { #[stable(feature = "rust1", since = "1.0.0")] impl Extend<(usize, V)> for VecMap { - fn extend>(&mut self, iter: Iter) { + fn extend>(&mut self, iter: I) { for (k, v) in iter { self.insert(k, v); } diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index fffba1561a380..2e9977cd3eb1d 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -147,7 +147,7 @@ impl IntoIterator for I { pub trait Extend { /// Extend a container with the elements yielded by an arbitrary iterator #[stable(feature = "rust1", since = "1.0.0")] - fn extend>(&mut self, iterator: T); + fn extend>(&mut self, iterable: T); } /// An extension trait providing numerous methods applicable to all iterators. diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 1b9f8b9901723..61b531054a07b 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1570,7 +1570,7 @@ impl Extend<(K, V)> for HashMap S: HashState, H: hash::Hasher { - fn extend>(&mut self, iter: T) { + fn extend>(&mut self, iter: T) { for (k, v) in iter { self.insert(k, v); } diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 5fbbcb3b347af..f5e57b78d2a63 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -636,7 +636,7 @@ impl Extend for HashSet S: HashState, H: hash::Hasher { - fn extend>(&mut self, iter: I) { + fn extend>(&mut self, iter: I) { for k in iter { self.insert(k); } diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 1d992668900f0..f25cc83b93e16 100755 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -110,7 +110,7 @@ use core::prelude::*; use ascii::*; use borrow::BorrowFrom; use cmp; -use iter; +use iter::{self, IntoIterator}; use mem; use ops::{self, Deref}; use string::CowString; @@ -961,7 +961,7 @@ impl<'a, P: ?Sized + 'a> iter::FromIterator<&'a P> for PathBuf where P: AsPath { } impl<'a, P: ?Sized + 'a> iter::Extend<&'a P> for PathBuf where P: AsPath { - fn extend>(&mut self, iter: I) { + fn extend>(&mut self, iter: I) { for p in iter { self.push(p) } diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index b610f6c370bb3..e7cb67c6287ed 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -32,7 +32,7 @@ use borrow::Cow; use cmp; use fmt; use hash::{Hash, Writer, Hasher}; -use iter::FromIterator; +use iter::{FromIterator, IntoIterator}; use mem; use num::Int; use ops; @@ -368,7 +368,8 @@ impl FromIterator for Wtf8Buf { /// This replaces surrogate code point pairs with supplementary code points, /// like concatenating ill-formed UTF-16 strings effectively would. impl Extend for Wtf8Buf { - fn extend>(&mut self, iterator: T) { + fn extend>(&mut self, iterable: T) { + let iterator = iterable.into_iter(); let (low, _high) = iterator.size_hint(); // Lower bound of one byte per code point (ASCII only) self.bytes.reserve(low); diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index b2009a7e84854..6a1fb4008ade0 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -11,7 +11,7 @@ use self::SmallVectorRepr::*; use self::IntoIterRepr::*; -use std::iter::FromIterator; +use std::iter::{IntoIterator, FromIterator}; use std::mem; use std::slice; use std::vec; @@ -38,7 +38,7 @@ impl FromIterator for SmallVector { } impl Extend for SmallVector { - fn extend>(&mut self, iter: I) { + fn extend>(&mut self, iter: I) { for val in iter { self.push(val); } From 66613e26b95438c02e2f5c273c557515454121f7 Mon Sep 17 00:00:00 2001 From: Alexis Date: Wed, 18 Feb 2015 13:06:21 -0500 Subject: [PATCH 48/76] make FromIterator use IntoIterator This breaks all implementors of FromIterator, as they must now accept IntoIterator instead of Iterator. The fix for this is generally trivial (change the bound, and maybe call into_iter() on the argument to get the old argument). Users of FromIterator should be unaffected because Iterators are IntoIterator. [breaking-change] --- src/libcollections/binary_heap.rs | 4 ++-- src/libcollections/bit.rs | 12 ++++++------ src/libcollections/btree/map.rs | 2 +- src/libcollections/btree/set.rs | 2 +- src/libcollections/enum_set.rs | 4 ++-- src/libcollections/linked_list.rs | 6 +++--- src/libcollections/string.rs | 8 ++++---- src/libcollections/vec.rs | 5 +++-- src/libcollections/vec_deque.rs | 3 ++- src/libcollections/vec_map.rs | 2 +- src/libcore/iter.rs | 4 ++-- src/libcore/option.rs | 6 +++--- src/libcore/result.rs | 7 ++++--- src/librustc/middle/check_match.rs | 6 +++--- src/libstd/collections/hash/map.rs | 3 ++- src/libstd/collections/hash/set.rs | 3 ++- src/libstd/path.rs | 2 +- src/libstd/sys/common/wtf8.rs | 4 ++-- src/libsyntax/owned_slice.rs | 6 +++--- src/libsyntax/util/small_vector.rs | 2 +- 20 files changed, 48 insertions(+), 43 deletions(-) diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index 2f994e94ccc3e..9f549fd723771 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -650,8 +650,8 @@ impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {} #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for BinaryHeap { - fn from_iter>(iter: Iter) -> BinaryHeap { - BinaryHeap::from_vec(iter.collect()) + fn from_iter>(iter: I) -> BinaryHeap { + BinaryHeap::from_vec(iter.into_iter().collect()) } } diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index c1d79d8204384..f4b65aab38b65 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -924,9 +924,9 @@ impl Default for BitVec { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for BitVec { - fn from_iter>(iterator: I) -> BitVec { - let mut ret = BitVec::new(); - ret.extend(iterator); + fn from_iter>(iter: I) -> BitVec { + let mut ret = Bitv::new(); + ret.extend(iter); ret } } @@ -1134,9 +1134,9 @@ impl Default for BitSet { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for BitSet { - fn from_iter>(iterator: I) -> BitSet { - let mut ret = BitSet::new(); - ret.extend(iterator); + fn from_iter>(iter: I) -> BitSet { + let mut ret = BitvSet::new(); + ret.extend(iter); ret } } diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 9273d50db856b..262084d5a9122 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -826,7 +826,7 @@ mod stack { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator<(K, V)> for BTreeMap { - fn from_iter>(iter: T) -> BTreeMap { + fn from_iter>(iter: T) -> BTreeMap { let mut map = BTreeMap::new(); map.extend(iter); map diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index d2241a6746499..6149718662314 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -473,7 +473,7 @@ impl BTreeSet { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for BTreeSet { - fn from_iter>(iter: Iter) -> BTreeSet { + fn from_iter>(iter: I) -> BTreeSet { let mut set = BTreeSet::new(); set.extend(iter); set diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 3f8c0121fafb5..140c9edb5a3a7 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -250,9 +250,9 @@ impl Iterator for Iter { } impl FromIterator for EnumSet { - fn from_iter>(iterator: I) -> EnumSet { + fn from_iter>(iter: I) -> EnumSet { let mut ret = EnumSet::new(); - ret.extend(iterator); + ret.extend(iter); ret } } diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 0ec1371c73cbf..bd8f508b70fab 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -834,9 +834,9 @@ impl DoubleEndedIterator for IntoIter { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for LinkedList { - fn from_iter>(iterator: T) -> LinkedList { - let mut ret = LinkedList::new(); - ret.extend(iterator); + fn from_iter>(iter: T) -> LinkedList { + let mut ret = DList::new(); + ret.extend(iter); ret } } diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index dc1158ecaf85e..627c357d8b3f8 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -709,18 +709,18 @@ impl Error for FromUtf16Error { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for String { - fn from_iter>(iterator: I) -> String { + fn from_iter>(iter: I) -> String { let mut buf = String::new(); - buf.extend(iterator); + buf.extend(iter); buf } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a> FromIterator<&'a str> for String { - fn from_iter>(iterator: I) -> String { + fn from_iter>(iter: I) -> String { let mut buf = String::new(); - buf.extend(iterator); + buf.extend(iter); buf } } diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index e4b090e4dd7ac..dd10a7582fb89 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1407,7 +1407,8 @@ impl ops::DerefMut for Vec { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for Vec { #[inline] - fn from_iter>(mut iterator: I) -> Vec { + fn from_iter>(iterable: I) -> Vec { + let mut iterator = iterable.into_iter(); let (lower, _) = iterator.size_hint(); let mut vector = Vec::with_capacity(lower); @@ -1651,7 +1652,7 @@ pub type CowVec<'a, T> = Cow<'a, Vec, [T]>; #[unstable(feature = "collections")] impl<'a, T> FromIterator for CowVec<'a, T> where T: Clone { - fn from_iter>(it: I) -> CowVec<'a, T> { + fn from_iter>(it: I) -> CowVec<'a, T> { Cow::Owned(FromIterator::from_iter(it)) } } diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index cc01e800f6073..c281d5de02723 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -1701,7 +1701,8 @@ impl IndexMut for VecDeque { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for VecDeque { - fn from_iter>(iterator: T) -> VecDeque { + fn from_iter>(iterable: T) -> VecDeque { + let iterator = iterable.into_iter(); let (lower, _) = iterator.size_hint(); let mut deq = VecDeque::with_capacity(lower); deq.extend(iterator); diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 7085111d6a87b..4431bfddbd74c 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -661,7 +661,7 @@ impl fmt::Debug for VecMap { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator<(usize, V)> for VecMap { - fn from_iter>(iter: Iter) -> VecMap { + fn from_iter>(iter: I) -> VecMap { let mut map = VecMap::new(); map.extend(iter); map diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 2e9977cd3eb1d..355bf3a28cbac 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -113,9 +113,9 @@ impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I { #[rustc_on_unimplemented="a collection of type `{Self}` cannot be \ built from an iterator over elements of type `{A}`"] pub trait FromIterator { - /// Build a container with elements from an external iterator. + /// Build a container with elements from something iterable. #[stable(feature = "rust1", since = "1.0.0")] - fn from_iter>(iterator: T) -> Self; + fn from_iter>(iterator: T) -> Self; } /// Conversion into an `Iterator` diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 9a89682127fb1..abfef72a5dbc3 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -149,7 +149,7 @@ use clone::Clone; use cmp::{Eq, Ord}; use default::Default; use iter::{ExactSizeIterator}; -use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator}; +use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, IntoIterator}; use mem; use ops::{Deref, FnOnce}; use result::Result::{Ok, Err}; @@ -909,7 +909,7 @@ impl> FromIterator> for Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn from_iter>>(iter: I) -> Option { + fn from_iter>>(iter: I) -> Option { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. @@ -934,7 +934,7 @@ impl> FromIterator> for Option { } } - let mut adapter = Adapter { iter: iter, found_none: false }; + let mut adapter = Adapter { iter: iter.into_iter(), found_none: false }; let v: V = FromIterator::from_iter(adapter.by_ref()); if adapter.found_none { diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 1a874ee178ba0..23e936a75d709 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -230,7 +230,8 @@ use self::Result::{Ok, Err}; use clone::Clone; use fmt; -use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator}; +use iter::{Iterator, IteratorExt, DoubleEndedIterator, + FromIterator, ExactSizeIterator, IntoIterator}; use ops::{FnMut, FnOnce}; use option::Option::{self, None, Some}; use slice::AsSlice; @@ -906,7 +907,7 @@ impl> FromIterator> for Result { /// assert!(res == Ok(vec!(2, 3))); /// ``` #[inline] - fn from_iter>>(iter: I) -> Result { + fn from_iter>>(iter: I) -> Result { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. @@ -931,7 +932,7 @@ impl> FromIterator> for Result { } } - let mut adapter = Adapter { iter: iter, err: None }; + let mut adapter = Adapter { iter: iter.into_iter(), err: None }; let v: V = FromIterator::from_iter(adapter.by_ref()); match adapter.err { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 03456f8529028..3b29c43ce8ced 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -25,7 +25,7 @@ use middle::ty::*; use middle::ty; use std::cmp::Ordering; use std::fmt; -use std::iter::{range_inclusive, AdditiveIterator, FromIterator, repeat}; +use std::iter::{range_inclusive, AdditiveIterator, FromIterator, IntoIterator, repeat}; use std::num::Float; use std::slice; use syntax::ast::{self, DUMMY_NODE_ID, NodeId, Pat}; @@ -94,8 +94,8 @@ impl<'a> fmt::Debug for Matrix<'a> { } impl<'a> FromIterator> for Matrix<'a> { - fn from_iter>>(iterator: T) -> Matrix<'a> { - Matrix(iterator.collect()) + fn from_iter>>(iter: T) -> Matrix<'a> { + Matrix(iter.into_iter().collect()) } } diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 61b531054a07b..0ce5b164ca13b 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1555,7 +1555,8 @@ impl FromIterator<(K, V)> for HashMap S: HashState + Default, H: hash::Hasher { - fn from_iter>(iter: T) -> HashMap { + fn from_iter>(iterable: T) -> HashMap { + let iter = iterable.into_iter(); let lower = iter.size_hint().0; let mut map = HashMap::with_capacity_and_hash_state(lower, Default::default()); diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index f5e57b78d2a63..593248fd5c602 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -622,7 +622,8 @@ impl FromIterator for HashSet S: HashState + Default, H: hash::Hasher { - fn from_iter>(iter: I) -> HashSet { + fn from_iter>(iterable: I) -> HashSet { + let iter = iterable.into_iter(); let lower = iter.size_hint().0; let mut set = HashSet::with_capacity_and_hash_state(lower, Default::default()); set.extend(iter); diff --git a/src/libstd/path.rs b/src/libstd/path.rs index f25cc83b93e16..2ad07462f20f7 100755 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -953,7 +953,7 @@ impl PathBuf { } impl<'a, P: ?Sized + 'a> iter::FromIterator<&'a P> for PathBuf where P: AsPath { - fn from_iter>(iter: I) -> PathBuf { + fn from_iter>(iter: I) -> PathBuf { let mut buf = PathBuf::new(""); buf.extend(iter); buf diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index e7cb67c6287ed..da5ab8e434a7b 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -356,9 +356,9 @@ impl Wtf8Buf { /// This replaces surrogate code point pairs with supplementary code points, /// like concatenating ill-formed UTF-16 strings effectively would. impl FromIterator for Wtf8Buf { - fn from_iter>(iterator: T) -> Wtf8Buf { + fn from_iter>(iter: T) -> Wtf8Buf { let mut string = Wtf8Buf::new(); - string.extend(iterator); + string.extend(iter); string } } diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs index 0f9a56baa170b..f5201d4a8bc68 100644 --- a/src/libsyntax/owned_slice.rs +++ b/src/libsyntax/owned_slice.rs @@ -10,7 +10,7 @@ use std::default::Default; use std::fmt; -use std::iter::FromIterator; +use std::iter::{IntoIterator, FromIterator}; use std::ops::Deref; use std::vec; use serialize::{Encodable, Decodable, Encoder, Decoder}; @@ -77,8 +77,8 @@ impl Clone for OwnedSlice { } impl FromIterator for OwnedSlice { - fn from_iter>(iter: I) -> OwnedSlice { - OwnedSlice::from_vec(iter.collect()) + fn from_iter>(iter: I) -> OwnedSlice { + OwnedSlice::from_vec(iter.into_iter().collect()) } } diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index 6a1fb4008ade0..0a39d3809045a 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -30,7 +30,7 @@ enum SmallVectorRepr { } impl FromIterator for SmallVector { - fn from_iter>(iter: I) -> SmallVector { + fn from_iter>(iter: I) -> SmallVector { let mut v = SmallVector::zero(); v.extend(iter); v From 204e2bd442f1fe7db7201c048300dbf66f123e30 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Wed, 18 Feb 2015 21:37:48 +0200 Subject: [PATCH 49/76] Style all docblock links properly Fixes #22493 --- src/librustdoc/html/static/main.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css index a4263badb0136..2f0755ecb898a 100644 --- a/src/librustdoc/html/static/main.css +++ b/src/librustdoc/html/static/main.css @@ -374,8 +374,8 @@ a { color: #000; background: transparent; } -p a { color: #4e8bca; } -p a:hover { text-decoration: underline; } +.docblock a { color: #4e8bca; } +.docblock a:hover { text-decoration: underline; } .content span.trait, .content a.trait, .block a.current.trait { color: #ed9603; } .content span.mod, .content a.mod, block a.current.mod { color: #4d76ae; } From a36fc2d66cb95382008a4236f3a803350b64d784 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Wed, 18 Feb 2015 21:38:32 +0200 Subject: [PATCH 50/76] Fix inconsistent spacing of collapse all button --- src/librustdoc/html/render.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 95994af7dc8de..fc3c87389917a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1404,8 +1404,7 @@ impl<'a> fmt::Display for Item<'a> { try!(write!(fmt, r##" - [-] -  [+] + [-] [+] "##)); // Write `src` tag From a2393e665d484b088773dea58e9f4fa92e8871a7 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 18 Feb 2015 16:38:39 -0500 Subject: [PATCH 51/76] WIP -- improve documentation on the phantom traits --- src/libcore/marker.rs | 76 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 5c7ec423e7c9a..0e217f6d574dd 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -282,11 +282,65 @@ macro_rules! impls{ pub trait MarkerTrait : PhantomFn { } impl MarkerTrait for T { } -/// `PhantomFn` is a marker trait for use with traits that do not -/// include any methods. +/// `PhantomFn` is a marker trait for use with traits that contain +/// type or lifetime parameters that do not appear in any of their +/// methods. In that case, you can either remove those parameters, or +/// add a `PhantomFn` supertrait that reflects the signature of +/// methods that compiler should "pretend" exists. This most commonly +/// occurs for traits with no methods: in that particular case, you +/// can extend `MarkerTrait`, which is equivalent to +/// `PhantomFn`. +/// +/// # Example +/// +/// As an example, consider a trait with no methods like `Even`, meant +/// to represent types that are "even": +/// +/// ```rust +/// trait Even { } +/// ``` /// -/// FIXME. Better documentation needed here! +/// In this case, because the implicit parameter `Self` is unused, the +/// compiler will issue an error. The only purpose of this trait is to +/// categorize types (and hence instances of those types) as "even" or +/// not, so if we *were* going to have a method, it might look like: +/// +/// ```rust +/// trait Even { +/// fn is_even(self) -> bool { true } +/// } +/// ``` +/// +/// Therefore, we can model a method like this as follows: +/// +/// ```rust +/// use std::marker::PhantomFn +/// trait Even : PhantomFn { } +/// ``` +/// +/// Another equivalent, but clearer, option would be to use +/// `MarkerTrait`: +/// +/// ```rust +/// use std::marker::MarkerTrait; +/// trait Even : MarkerTrait { } +/// ``` +/// +/// # Parameters +/// +/// - `A` represents the type of the method's argument. You can use a +/// tuple to represent "multiple" arguments. Any types appearing here +/// will be considered "contravariant". +/// - `R`, if supplied, represents the method's return type. This defaults +/// to `()` as it is rarely needed. +/// +/// # Additional reading +/// +/// More details and background can be found in [RFC 738][738]. +/// +/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md #[lang="phantom_fn"] +#[stable(feature = "rust1", since = "1.0.0")] pub trait PhantomFn { } #[cfg(stage0)] // built into the trait matching system after stage0 @@ -298,18 +352,30 @@ impl PhantomFn for U { } pub struct PhantomData; /// `PhantomData` is a way to tell the compiler about fake fields. +/// Phantom data is required whenever type parameters are not used. /// The idea is that if the compiler encounters a `PhantomData` /// instance, it will behave *as if* an instance of the type `T` were /// present for the purpose of various automatic analyses. /// -/// FIXME. Better documentation needed here! +/// For example, embedding a `PhantomData` will inform the compiler +/// that one or more instances of the type `T` could be dropped when +/// instances of the type itself is dropped, though that may not be +/// apparent from the other structure of the type itself. This is +/// commonly necessary if the structure is using an unsafe pointer +/// like `*mut T` whose referent may be dropped when the type is +/// dropped, as a `*mut T` is otherwise not treated as owned. +/// +/// FIXME. Better documentation and examples of common patterns needed +/// here! For now, please see [RFC 738][738] for more information. +/// +/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md #[cfg(not(stage0))] #[lang="phantom_data"] +#[stable(feature = "rust1", since = "1.0.0")] pub struct PhantomData; impls! { PhantomData } - #[cfg(not(stage0))] mod impls { use super::{Send, Sync, Sized}; From 4acc48310678f67461c8db15f6f9351577a53f09 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 15 Feb 2015 20:20:25 -0800 Subject: [PATCH 52/76] Simplify README by not talking about the source tarball option I believe that few enough people build from source tarballs that we don't have to talk about it explicitly. --- README.md | 19 ++++--------------- src/llvm | 2 +- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 065c4ed7c7bcb..a0ebfc6927322 100644 --- a/README.md +++ b/README.md @@ -19,22 +19,14 @@ Read ["Installing Rust"][install] from [The Book][trpl]. * `curl` * `git` -2. Download and build Rust: - - You can either download a [tarball] or build directly from the [repo]. - - To build from the [tarball] do: - - $ curl -O https://static.rust-lang.org/dist/rustc-nightly-src.tar.gz - $ tar -xzf rustc-nightly-src.tar.gz - $ cd rustc-nightly - - Or to build from the [repo] do: +2. Clone the [source] with git: $ git clone https://github.com/rust-lang/rust.git $ cd rust - Now that you have Rust's source code, you can configure and build it: +[source]: https://github.com/rust-lang/rust + +3. Build and install: $ ./configure $ make && make install @@ -72,9 +64,6 @@ $ pacman -S base-devel $ ./configure $ make && make install -[repo]: https://github.com/rust-lang/rust -[tarball]: https://static.rust-lang.org/dist/rustc-nightly-src.tar.gz - ## Notes Since the Rust compiler is written in Rust, it must be built by a diff --git a/src/llvm b/src/llvm index 2089cab13e7f9..4891e6382e3e8 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 2089cab13e7f92b487ba0dc1df9f6c05116b004a +Subproject commit 4891e6382e3e8aa89d530aa18427836428c47157 From 21ed20baf932dd092cc80b0f4ade38dd7aa7c788 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 15 Feb 2015 20:41:16 -0800 Subject: [PATCH 53/76] README: Give a hint about how to build Cargo from source. Just a hint. --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a0ebfc6927322..f13bc287fabdb 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,10 @@ Read ["Installing Rust"][install] from [The Book][trpl]. When complete, `make install` will place several programs into `/usr/local/bin`: `rustc`, the Rust compiler, and `rustdoc`, the - API-documentation tool. + API-documentation tool. This install does not include [Cargo], + Rust's package manager, which you may also want to build. + +[Cargo]: https://github.com/rust-lang/cargo ### Building on Windows From 9265e13867ddad092e709097e20ff3b513635670 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 15 Feb 2015 20:46:21 -0800 Subject: [PATCH 54/76] README: Make the wiki links more useful. The page we want them to find is 'getting started developing'. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f13bc287fabdb..1caabfd27dc89 100644 --- a/README.md +++ b/README.md @@ -86,8 +86,9 @@ supported build environments that are most likely to work. Rust currently needs about 1.5 GiB of RAM to build without swapping; if it hits swap, it will take a very long time to build. -There is a lot more documentation in the [wiki]. +There is more advice about [hacking on Rust][hack] on the [wiki]. +[hack]: https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust [wiki]: https://github.com/rust-lang/rust/wiki ## Getting help From 46189559a9449de3a7eacf70652aec8a994c9220 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 15 Feb 2015 20:58:06 -0800 Subject: [PATCH 55/76] README: Add a link to #rust --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 1caabfd27dc89..e37f1aec2d573 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,14 @@ The Rust community congregates in a few places: To contribute to Rust, please see [CONTRIBUTING.md](CONTRIBUTING.md). +Rust has an [IRC] culture and most real-time collaboration happens in a +variety of channels on Mozilla's IRC network, irc.mozilla.org. The +most popular channel is [#rust], a venue for general discussion about +Rust, and a good place to ask for help, + +[IRC]: https://en.wikipedia.org/wiki/Internet_Relay_Chat +[#rust]: https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust + ## License Rust is primarily distributed under the terms of both the MIT license From aaabdbfe049cb4eaa2a353f4ce1bc59862a6b49e Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 15 Feb 2015 21:08:32 -0800 Subject: [PATCH 56/76] README: Add one sentence about what Rust is. Most people don't know what Rust is. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e37f1aec2d573..fd6d3723276f9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # The Rust Programming Language This is a compiler for Rust, including standard libraries, tools and -documentation. +documentation. Rust is a systems programming language that is fast, +memory safe and multithreaded, but does not employ a garbage collector +or otherwise impose significant runtime overhead. ## Quick Start From 73cc4ed4daa0d33ddbcb06fb918fbe9a297f8b8a Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 15 Feb 2015 21:20:27 -0800 Subject: [PATCH 57/76] README: Simplify markdown --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fd6d3723276f9..36f4e1fa5be02 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,10 @@ or otherwise impose significant runtime overhead. ## Quick Start -Read ["Installing Rust"][install] from [The Book][trpl]. +Read ["Installing Rust"] from [The Book]. -[install]: http://doc.rust-lang.org/book/installing-rust.html -[trpl]: http://doc.rust-lang.org/book/index.html +["Installing Rust"]: http://doc.rust-lang.org/book/installing-rust.html +[The Book]: http://doc.rust-lang.org/book/index.html ## Building from Source From 7430e58e65b26e4b5b738392b192e4b9c836797b Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 18 Feb 2015 13:46:20 -0800 Subject: [PATCH 58/76] Address review feedback --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 36f4e1fa5be02..85c2721821836 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Read ["Installing Rust"] from [The Book]. * `curl` * `git` -2. Clone the [source] with git: +2. Clone the [source] with `git`: $ git clone https://github.com/rust-lang/rust.git $ cd rust @@ -90,7 +90,7 @@ swap, it will take a very long time to build. There is more advice about [hacking on Rust][hack] on the [wiki]. -[hack]: https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust +[hack]: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md [wiki]: https://github.com/rust-lang/rust/wiki ## Getting help @@ -115,7 +115,7 @@ most popular channel is [#rust], a venue for general discussion about Rust, and a good place to ask for help, [IRC]: https://en.wikipedia.org/wiki/Internet_Relay_Chat -[#rust]: https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust +[#rust]: irc://irc.mozilla.org/rust ## License From c273571bfdb5b3aefba1a29a19b6da601d8c5626 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 18 Feb 2015 13:48:46 -0800 Subject: [PATCH 59/76] Remove mention of wiki from README --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 85c2721821836..b6a73730d351c 100644 --- a/README.md +++ b/README.md @@ -88,10 +88,9 @@ supported build environments that are most likely to work. Rust currently needs about 1.5 GiB of RAM to build without swapping; if it hits swap, it will take a very long time to build. -There is more advice about [hacking on Rust][hack] on the [wiki]. +There is more advice about hacking on Rust in [CONTRIBUTING.md]. -[hack]: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md -[wiki]: https://github.com/rust-lang/rust/wiki +[CONTRIBUTING.md]: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md ## Getting help From d622235b303409016d8b764b4ae7f2098223ce4d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 18 Feb 2015 17:14:27 -0500 Subject: [PATCH 60/76] Add deprecated versions of the old markers and integrate them back into the variance analysis. --- src/libcore/marker.rs | 37 +++++++++++++++++++ src/librustc/middle/lang_items.rs | 8 ++++ src/librustc_typeck/variance.rs | 12 +++++- .../variance-deprecated-markers.rs | 35 ++++++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/variance-deprecated-markers.rs diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 0e217f6d574dd..c97b1713abc57 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -383,3 +383,40 @@ mod impls { unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {} unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {} } + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<&'a ()>`")] +#[lang="contravariant_lifetime"] +pub struct ContravariantLifetime<'a>; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData`")] +#[lang="covariant_lifetime"] +pub struct CovariantLifetime<'a>; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData>`")] +#[lang="invariant_lifetime"] +pub struct InvariantLifetime<'a>; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData`")] +#[lang="contravariant_type"] +pub struct ContravariantType; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData`")] +#[lang="covariant_type"] +#[cfg(not(stage0))] +pub struct CovariantType; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData>`")] +#[lang="invariant_type"] +pub struct InvariantType; diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index acebb97a0c13f..68c80def7ff40 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -315,6 +315,14 @@ lets_do_this! { PhantomFnItem, "phantom_fn", phantom_fn; PhantomDataItem, "phantom_data", phantom_data; + // Deprecated: + CovariantTypeItem, "covariant_type", covariant_type; + ContravariantTypeItem, "contravariant_type", contravariant_type; + InvariantTypeItem, "invariant_type", invariant_type; + CovariantLifetimeItem, "covariant_lifetime", covariant_lifetime; + ContravariantLifetimeItem, "contravariant_lifetime", contravariant_lifetime; + InvariantLifetimeItem, "invariant_lifetime", invariant_lifetime; + NoCopyItem, "no_copy_bound", no_copy_bound; ManagedItem, "managed_bound", managed_bound; diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index be7138d54f8d0..d2a400880d5b6 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -335,7 +335,17 @@ fn lang_items(tcx: &ty::ctxt) -> Vec<(ast::NodeId,Vec)> { let all = vec![ (tcx.lang_items.phantom_fn(), vec![ty::Contravariant, ty::Covariant]), (tcx.lang_items.phantom_data(), vec![ty::Covariant]), - (tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant])]; + (tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant]), + + // Deprecated: + (tcx.lang_items.covariant_type(), vec![ty::Covariant]), + (tcx.lang_items.contravariant_type(), vec![ty::Contravariant]), + (tcx.lang_items.invariant_type(), vec![ty::Invariant]), + (tcx.lang_items.covariant_lifetime(), vec![ty::Covariant]), + (tcx.lang_items.contravariant_lifetime(), vec![ty::Contravariant]), + (tcx.lang_items.invariant_lifetime(), vec![ty::Invariant]), + + ]; all.into_iter() .filter(|&(ref d,_)| d.is_some()) diff --git a/src/test/compile-fail/variance-deprecated-markers.rs b/src/test/compile-fail/variance-deprecated-markers.rs new file mode 100644 index 0000000000000..8f9d24cb132c2 --- /dev/null +++ b/src/test/compile-fail/variance-deprecated-markers.rs @@ -0,0 +1,35 @@ +// Copyright 2015 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. + +// Test that the deprecated markers still have their old effect. + +#![feature(rustc_attrs)] + +use std::marker; + +#[rustc_variance] +struct A(marker::CovariantType); //~ ERROR types=[[+];[];[]] + +#[rustc_variance] +struct B(marker::ContravariantType); //~ ERROR types=[[-];[];[]] + +#[rustc_variance] +struct C(marker::InvariantType); //~ ERROR types=[[o];[];[]] + +#[rustc_variance] +struct D<'a>(marker::CovariantLifetime<'a>); //~ ERROR regions=[[+];[];[]] + +#[rustc_variance] +struct E<'a>(marker::ContravariantLifetime<'a>); //~ ERROR regions=[[-];[];[]] + +#[rustc_variance] +struct F<'a>(marker::InvariantLifetime<'a>); //~ ERROR regions=[[o];[];[]] + +fn main() { } From 1860ee521aa6096eb7f5410a64b53311fb0d2d0e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 17 Feb 2015 22:47:40 -0800 Subject: [PATCH 61/76] std: Implement CString-related RFCs This commit is an implementation of [RFC 592][r592] and [RFC 840][r840]. These two RFCs tweak the behavior of `CString` and add a new `CStr` unsized slice type to the module. [r592]: https://github.com/rust-lang/rfcs/blob/master/text/0592-c-str-deref.md [r840]: https://github.com/rust-lang/rfcs/blob/master/text/0840-no-panic-in-c-string.md The new `CStr` type is only constructable via two methods: 1. By `deref`'ing from a `CString` 2. Unsafely via `CStr::from_ptr` The purpose of `CStr` is to be an unsized type which is a thin pointer to a `libc::c_char` (currently it is a fat pointer slice due to implementation limitations). Strings from C can be safely represented with a `CStr` and an appropriate lifetime as well. Consumers of `&CString` should now consume `&CStr` instead to allow producers to pass in C-originating strings instead of just Rust-allocated strings. A new constructor was added to `CString`, `new`, which takes `T: IntoBytes` instead of separate `from_slice` and `from_vec` methods (both have been deprecated in favor of `new`). The `new` method returns a `Result` instead of panicking. The error variant contains the relevant information about where the error happened and bytes (if present). Conversions are provided to the `io::Error` and `old_io::IoError` types via the `FromError` trait which translate to `InvalidInput`. This is a breaking change due to the modification of existing `#[unstable]` APIs and new deprecation, and more detailed information can be found in the two RFCs. Notable breakage includes: * All construction of `CString` now needs to use `new` and handle the outgoing `Result`. * Usage of `CString` as a byte slice now explicitly needs a `.as_bytes()` call. * The `as_slice*` methods have been removed in favor of just having the `as_bytes*` methods. Closes #22469 Closes #22470 [breaking-change] --- src/doc/trpl/ffi.md | 4 +- src/librustc/metadata/loader.rs | 2 +- src/librustc_llvm/archive_ro.rs | 4 +- src/librustc_llvm/lib.rs | 2 +- src/librustc_trans/back/lto.rs | 2 +- src/librustc_trans/back/write.rs | 28 +- src/librustc_trans/trans/asm.rs | 4 +- src/librustc_trans/trans/base.rs | 22 +- src/librustc_trans/trans/builder.rs | 4 +- src/librustc_trans/trans/common.rs | 7 +- src/librustc_trans/trans/context.rs | 10 +- src/librustc_trans/trans/debuginfo.rs | 50 +-- src/librustc_trans/trans/foreign.rs | 6 +- src/librustc_trans/trans/glue.rs | 2 +- src/librustc_trans/trans/type_.rs | 2 +- src/librustdoc/flock.rs | 2 +- src/librustdoc/html/markdown.rs | 4 +- src/libstd/dynamic_lib.rs | 8 +- src/libstd/ffi/c_str.rs | 402 +++++++++++++++---- src/libstd/ffi/mod.rs | 4 +- src/libstd/old_io/net/pipe.rs | 6 +- src/libstd/old_io/process.rs | 26 +- src/libstd/rt/args.rs | 9 +- src/libstd/sys/common/net.rs | 17 +- src/libstd/sys/common/net2.rs | 2 +- src/libstd/sys/unix/backtrace.rs | 6 +- src/libstd/sys/unix/ext.rs | 12 +- src/libstd/sys/unix/fs.rs | 42 +- src/libstd/sys/unix/fs2.rs | 44 +- src/libstd/sys/unix/mod.rs | 5 +- src/libstd/sys/unix/net.rs | 4 +- src/libstd/sys/unix/os.rs | 28 +- src/libstd/sys/unix/pipe.rs | 6 +- src/libstd/sys/unix/process2.rs | 8 +- src/libstd/sys/unix/thread.rs | 6 +- src/libsyntax/diagnostic.rs | 35 +- src/test/run-pass/c-stack-returning-int64.rs | 4 +- src/test/run-pass/foreign-fn-linkname.rs | 2 +- src/test/run-pass/rename-directory.rs | 6 +- src/test/run-pass/variadic-ffi.rs | 8 +- 40 files changed, 555 insertions(+), 290 deletions(-) diff --git a/src/doc/trpl/ffi.md b/src/doc/trpl/ffi.md index f2b95f19edce2..60750160f5fe3 100644 --- a/src/doc/trpl/ffi.md +++ b/src/doc/trpl/ffi.md @@ -435,8 +435,8 @@ extern { } fn main() { - let prompt = CString::from_slice(b"[my-awesome-shell] $"); - unsafe { + let prompt = CString::new("[my-awesome-shell] $").unwrap(); + unsafe { rl_prompt = prompt.as_ptr(); println!("{:?}", rl_prompt); diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 3158ccd076522..89f19b6c47c51 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -744,7 +744,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result Option { unsafe { - let s = CString::from_slice(dst.as_vec()); + let s = CString::new(dst.as_vec()).unwrap(); let ar = ::LLVMRustOpenArchive(s.as_ptr()); if ar.is_null() { None @@ -44,7 +44,7 @@ impl ArchiveRO { pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> { unsafe { let mut size = 0 as libc::size_t; - let file = CString::from_slice(file.as_bytes()); + let file = CString::new(file).unwrap(); let ptr = ::LLVMRustArchiveReadSection(self.ptr, file.as_ptr(), &mut size); if ptr.is_null() { diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index aa90d7c851ba6..c3fe23eff4690 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -2149,7 +2149,7 @@ impl Drop for TargetData { } pub fn mk_target_data(string_rep: &str) -> TargetData { - let string_rep = CString::from_slice(string_rep.as_bytes()); + let string_rep = CString::new(string_rep).unwrap(); TargetData { lltd: unsafe { LLVMCreateTargetData(string_rep.as_ptr()) } } diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index c88e76f427073..9d604695cf75f 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -140,7 +140,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, // Internalize everything but the reachable symbols of the current module let cstrs: Vec = reachable.iter().map(|s| { - CString::from_slice(s.as_bytes()) + CString::new(s.clone()).unwrap() }).collect(); let arr: Vec<*const libc::c_char> = cstrs.iter().map(|c| c.as_ptr()).collect(); let ptr = arr.as_ptr(); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 9934d9993d61d..20cd1624a8c97 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -22,7 +22,7 @@ use syntax::codemap; use syntax::diagnostic; use syntax::diagnostic::{Emitter, Handler, Level, mk_handler}; -use std::ffi::{self, CString}; +use std::ffi::{CStr, CString}; use std::old_io::Command; use std::old_io::fs; use std::iter::Unfold; @@ -49,7 +49,7 @@ pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! { if cstr == ptr::null() { handler.fatal(&msg[]); } else { - let err = ffi::c_str_to_bytes(&cstr); + let err = CStr::from_ptr(cstr).to_bytes(); let err = String::from_utf8_lossy(err).to_string(); libc::free(cstr as *mut _); handler.fatal(&format!("{}: {}", @@ -67,7 +67,7 @@ pub fn write_output_file( output: &Path, file_type: llvm::FileType) { unsafe { - let output_c = CString::from_slice(output.as_vec()); + let output_c = CString::new(output.as_vec()).unwrap(); let result = llvm::LLVMRustWriteOutputFile( target, pm, m, output_c.as_ptr(), file_type); if !result { @@ -221,13 +221,13 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef { let triple = &sess.target.target.llvm_target[]; let tm = unsafe { - let triple = CString::from_slice(triple.as_bytes()); + let triple = CString::new(triple.as_bytes()).unwrap(); let cpu = match sess.opts.cg.target_cpu { Some(ref s) => &**s, None => &*sess.target.target.options.cpu }; - let cpu = CString::from_slice(cpu.as_bytes()); - let features = CString::from_slice(target_feature(sess).as_bytes()); + let cpu = CString::new(cpu.as_bytes()).unwrap(); + let features = CString::new(target_feature(sess).as_bytes()).unwrap(); llvm::LLVMRustCreateTargetMachine( triple.as_ptr(), cpu.as_ptr(), features.as_ptr(), code_model, @@ -380,7 +380,7 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo } llvm::diagnostic::Optimization(opt) => { - let pass_name = str::from_utf8(ffi::c_str_to_bytes(&opt.pass_name)) + let pass_name = str::from_utf8(CStr::from_ptr(opt.pass_name).to_bytes()) .ok() .expect("got a non-UTF8 pass name from LLVM"); let enabled = match cgcx.remark { @@ -424,7 +424,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_no_opt_bc { let ext = format!("{}.no-opt.bc", name_extra); let out = output_names.with_extension(&ext); - let out = CString::from_slice(out.as_vec()); + let out = CString::new(out.as_vec()).unwrap(); llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()); } @@ -440,7 +440,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, // If we're verifying or linting, add them to the function pass // manager. let addpass = |pass: &str| { - let pass = CString::from_slice(pass.as_bytes()); + let pass = CString::new(pass).unwrap(); llvm::LLVMRustAddPass(fpm, pass.as_ptr()) }; if !config.no_verify { assert!(addpass("verify")); } @@ -453,7 +453,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, } for pass in &config.passes { - let pass = CString::from_slice(pass.as_bytes()); + let pass = CString::new(pass.clone()).unwrap(); if !llvm::LLVMRustAddPass(mpm, pass.as_ptr()) { cgcx.handler.warn(&format!("unknown pass {:?}, ignoring", pass)); } @@ -477,7 +477,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_lto_bc { let name = format!("{}.lto.bc", name_extra); let out = output_names.with_extension(&name); - let out = CString::from_slice(out.as_vec()); + let out = CString::new(out.as_vec()).unwrap(); llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()); } }, @@ -511,7 +511,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_bc { let ext = format!("{}.bc", name_extra); let out = output_names.with_extension(&ext); - let out = CString::from_slice(out.as_vec()); + let out = CString::new(out.as_vec()).unwrap(); llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()); } @@ -519,7 +519,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_ir { let ext = format!("{}.ll", name_extra); let out = output_names.with_extension(&ext); - let out = CString::from_slice(out.as_vec()); + let out = CString::new(out.as_vec()).unwrap(); with_codegen(tm, llmod, config.no_builtins, |cpm| { llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr()); }) @@ -1004,7 +1004,7 @@ unsafe fn configure_llvm(sess: &Session) { let mut llvm_args = Vec::new(); { let mut add = |arg: &str| { - let s = CString::from_slice(arg.as_bytes()); + let s = CString::new(arg).unwrap(); llvm_args.push(s.as_ptr()); llvm_c_strs.push(s); }; diff --git a/src/librustc_trans/trans/asm.rs b/src/librustc_trans/trans/asm.rs index e419be65fc4cc..53c21d04a9297 100644 --- a/src/librustc_trans/trans/asm.rs +++ b/src/librustc_trans/trans/asm.rs @@ -120,8 +120,8 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) ast::AsmIntel => llvm::AD_Intel }; - let asm = CString::from_slice(ia.asm.as_bytes()); - let constraints = CString::from_slice(constraints.as_bytes()); + let asm = CString::new(ia.asm.as_bytes()).unwrap(); + let constraints = CString::new(constraints).unwrap(); let r = InlineAsmCall(bcx, asm.as_ptr(), constraints.as_ptr(), diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 7f7b5cd800660..e136f61ce1cc8 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -86,7 +86,7 @@ use util::nodemap::NodeMap; use arena::TypedArena; use libc::{c_uint, uint64_t}; -use std::ffi::{self, CString}; +use std::ffi::{CStr, CString}; use std::cell::{Cell, RefCell}; use std::collections::HashSet; use std::mem; @@ -186,7 +186,7 @@ impl<'a, 'tcx> Drop for StatRecorder<'a, 'tcx> { pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv, ty: Type, output: ty::FnOutput) -> ValueRef { - let buf = CString::from_slice(name.as_bytes()); + let buf = CString::new(name).unwrap(); let llfn: ValueRef = unsafe { llvm::LLVMGetOrInsertFunction(ccx.llmod(), buf.as_ptr(), ty.to_ref()) }; @@ -340,7 +340,7 @@ pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId, None => () } unsafe { - let buf = CString::from_slice(name.as_bytes()); + let buf = CString::new(name.clone()).unwrap(); let c = llvm::LLVMAddGlobal(ccx.llmod(), ty.to_ref(), buf.as_ptr()); // Thread-local statics in some other crate need to *always* be linked // against in a thread-local fashion, so we need to be sure to apply the @@ -2788,7 +2788,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { &format!("Illegal null byte in export_name \ value: `{}`", sym)[]); } - let buf = CString::from_slice(sym.as_bytes()); + let buf = CString::new(sym.clone()).unwrap(); let g = llvm::LLVMAddGlobal(ccx.llmod(), llty, buf.as_ptr()); @@ -2826,7 +2826,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { §)[]); } unsafe { - let buf = CString::from_slice(sect.as_bytes()); + let buf = CString::new(sect.as_bytes()).unwrap(); llvm::LLVMSetSection(v, buf.as_ptr()); } }, @@ -2993,7 +2993,7 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec { let name = format!("rust_metadata_{}_{}", cx.link_meta().crate_name, cx.link_meta().crate_hash); - let buf = CString::from_vec(name.into_bytes()); + let buf = CString::new(name).unwrap(); let llglobal = unsafe { llvm::LLVMAddGlobal(cx.metadata_llmod(), val_ty(llconst).to_ref(), buf.as_ptr()) @@ -3001,7 +3001,7 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec { unsafe { llvm::LLVMSetInitializer(llglobal, llconst); let name = loader::meta_section_name(cx.sess().target.target.options.is_like_osx); - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name).unwrap(); llvm::LLVMSetSection(llglobal, name.as_ptr()) } return metadata; @@ -3039,8 +3039,8 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet) { continue } - let name = ffi::c_str_to_bytes(&llvm::LLVMGetValueName(val)) - .to_vec(); + let name = CStr::from_ptr(llvm::LLVMGetValueName(val)) + .to_bytes().to_vec(); declared.insert(name); } } @@ -3056,8 +3056,8 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet) { continue } - let name = ffi::c_str_to_bytes(&llvm::LLVMGetValueName(val)) - .to_vec(); + let name = CStr::from_ptr(llvm::LLVMGetValueName(val)) + .to_bytes().to_vec(); if !declared.contains(&name) && !reachable.contains(str::from_utf8(&name).unwrap()) { llvm::SetLinkage(val, llvm::InternalLinkage); diff --git a/src/librustc_trans/trans/builder.rs b/src/librustc_trans/trans/builder.rs index e268c2f0d5cc2..3bd0479c0d8e8 100644 --- a/src/librustc_trans/trans/builder.rs +++ b/src/librustc_trans/trans/builder.rs @@ -431,7 +431,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if name.is_empty() { llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname()) } else { - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name).unwrap(); llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), name.as_ptr()) } @@ -786,7 +786,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let comment_text = format!("{} {}", "#", sanitized.replace("\n", "\n\t# ")); self.count_insn("inlineasm"); - let comment_text = CString::from_vec(comment_text.into_bytes()); + let comment_text = CString::new(comment_text).unwrap(); let asm = unsafe { llvm::LLVMConstInlineAsm(Type::func(&[], &Type::void(self.ccx)).to_ref(), comment_text.as_ptr(), noname(), False, diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index d658003702dca..85ba3f938fdf2 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -488,7 +488,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> { opt_node_id: Option) -> Block<'a, 'tcx> { unsafe { - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name).unwrap(); let llbb = llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(), self.llfn, name.as_ptr()); @@ -761,7 +761,7 @@ pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef { pub fn C_floating(s: &str, t: Type) -> ValueRef { unsafe { - let s = CString::from_slice(s.as_bytes()); + let s = CString::new(s).unwrap(); llvm::LLVMConstRealOfString(t.to_ref(), s.as_ptr()) } } @@ -839,7 +839,8 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va !null_terminated as Bool); let gsym = token::gensym("str"); - let buf = CString::from_vec(format!("str{}", gsym.usize()).into_bytes()); + let buf = CString::new(format!("str{}", gsym.usize())); + let buf = buf.unwrap(); let g = llvm::LLVMAddGlobal(cx.llmod(), val_ty(sc).to_ref(), buf.as_ptr()); llvm::LLVMSetInitializer(g, sc); llvm::LLVMSetGlobalConstant(g, True); diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs index 96506291b5aae..cd5aed6d84636 100644 --- a/src/librustc_trans/trans/context.rs +++ b/src/librustc_trans/trans/context.rs @@ -225,15 +225,15 @@ impl<'a, 'tcx> Iterator for CrateContextMaybeIterator<'a, 'tcx> { unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) { let llcx = llvm::LLVMContextCreate(); - let mod_name = CString::from_slice(mod_name.as_bytes()); + let mod_name = CString::new(mod_name).unwrap(); let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx); - let data_layout = &*sess.target.target.data_layout; - let data_layout = CString::from_slice(data_layout.as_bytes()); + let data_layout = sess.target.target.data_layout.as_bytes(); + let data_layout = CString::new(data_layout).unwrap(); llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr()); - let llvm_target = &*sess.target.target.llvm_target; - let llvm_target = CString::from_slice(llvm_target.as_bytes()); + let llvm_target = sess.target.target.llvm_target.as_bytes(); + let llvm_target = CString::new(llvm_target).unwrap(); llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr()); (llcx, llmod) } diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 23498089c5839..653ad1b2b630b 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -809,8 +809,8 @@ pub fn create_global_var_metadata(cx: &CrateContext, namespace_node.mangled_name_of_contained_item(&var_name[]); let var_scope = namespace_node.scope; - let var_name = CString::from_slice(var_name.as_bytes()); - let linkage_name = CString::from_slice(linkage_name.as_bytes()); + let var_name = CString::new(var_name).unwrap(); + let linkage_name = CString::new(linkage_name).unwrap(); unsafe { llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx), var_scope, @@ -1379,8 +1379,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id); - let function_name = CString::from_slice(function_name.as_bytes()); - let linkage_name = CString::from_slice(linkage_name.as_bytes()); + let function_name = CString::new(function_name).unwrap(); + let linkage_name = CString::new(linkage_name).unwrap(); let fn_metadata = unsafe { llvm::LLVMDIBuilderCreateFunction( DIB(cx), @@ -1501,7 +1501,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let ident = special_idents::type_self; let ident = token::get_ident(ident); - let name = CString::from_slice(ident.as_bytes()); + let name = CString::new(ident.as_bytes()).unwrap(); let param_metadata = unsafe { llvm::LLVMDIBuilderCreateTemplateTypeParameter( DIB(cx), @@ -1535,7 +1535,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, if cx.sess().opts.debuginfo == FullDebugInfo { let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP); let ident = token::get_ident(ident); - let name = CString::from_slice(ident.as_bytes()); + let name = CString::new(ident.as_bytes()).unwrap(); let param_metadata = unsafe { llvm::LLVMDIBuilderCreateTemplateTypeParameter( DIB(cx), @@ -1601,7 +1601,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { path_bytes.insert(1, prefix[1]); } - CString::from_vec(path_bytes) + CString::new(path_bytes).unwrap() } _ => fallback_path(cx) } @@ -1614,8 +1614,8 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { (option_env!("CFG_VERSION")).expect("CFG_VERSION")); let compile_unit_name = compile_unit_name.as_ptr(); - let work_dir = CString::from_slice(work_dir.as_vec()); - let producer = CString::from_slice(producer.as_bytes()); + let work_dir = CString::new(work_dir.as_vec()).unwrap(); + let producer = CString::new(producer).unwrap(); let flags = "\0"; let split_name = "\0"; return unsafe { @@ -1632,7 +1632,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { }; fn fallback_path(cx: &CrateContext) -> CString { - CString::from_slice(cx.link_meta().crate_name.as_bytes()) + CString::new(cx.link_meta().crate_name.clone()).unwrap() } } @@ -1658,7 +1658,7 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, CapturedVariable => (0, DW_TAG_auto_variable) }; - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name.as_bytes()).unwrap(); match (variable_access, [].as_slice()) { (DirectVariable { alloca }, address_operations) | (IndirectVariable {alloca, address_operations}, _) => { @@ -1724,8 +1724,8 @@ fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile { full_path }; - let file_name = CString::from_slice(file_name.as_bytes()); - let work_dir = CString::from_slice(work_dir.as_bytes()); + let file_name = CString::new(file_name).unwrap(); + let work_dir = CString::new(work_dir).unwrap(); let file_metadata = unsafe { llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name.as_ptr(), work_dir.as_ptr()) @@ -1800,7 +1800,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let llvm_type = type_of::type_of(cx, t); let (size, align) = size_and_align_of(cx, llvm_type); - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name).unwrap(); let ty_metadata = unsafe { llvm::LLVMDIBuilderCreateBasicType( DIB(cx), @@ -1820,7 +1820,7 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let pointer_llvm_type = type_of::type_of(cx, pointer_type); let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type); let name = compute_debuginfo_type_name(cx, pointer_type, false); - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name).unwrap(); let ptr_metadata = unsafe { llvm::LLVMDIBuilderCreatePointerType( DIB(cx), @@ -2445,7 +2445,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, .iter() .map(|v| { let token = token::get_name(v.name); - let name = CString::from_slice(token.as_bytes()); + let name = CString::new(token.as_bytes()).unwrap(); unsafe { llvm::LLVMDIBuilderCreateEnumerator( DIB(cx), @@ -2475,7 +2475,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, codemap::DUMMY_SP); let discriminant_name = get_enum_discriminant_name(cx, enum_def_id); - let name = CString::from_slice(discriminant_name.as_bytes()); + let name = CString::new(discriminant_name.as_bytes()).unwrap(); let discriminant_type_metadata = unsafe { llvm::LLVMDIBuilderCreateEnumerationType( DIB(cx), @@ -2518,8 +2518,8 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, .borrow() .get_unique_type_id_as_string(unique_type_id); - let enum_name = CString::from_slice(enum_name.as_bytes()); - let unique_type_id_str = CString::from_slice(unique_type_id_str.as_bytes()); + let enum_name = CString::new(enum_name).unwrap(); + let unique_type_id_str = CString::new(unique_type_id_str.as_bytes()).unwrap(); let enum_metadata = unsafe { llvm::LLVMDIBuilderCreateUnionType( DIB(cx), @@ -2644,7 +2644,8 @@ fn set_members_of_composite_type(cx: &CrateContext, ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i) }; - let member_name = CString::from_slice(member_description.name.as_bytes()); + let member_name = member_description.name.as_bytes(); + let member_name = CString::new(member_name).unwrap(); unsafe { llvm::LLVMDIBuilderCreateMemberType( DIB(cx), @@ -2681,8 +2682,8 @@ fn create_struct_stub(cx: &CrateContext, let unique_type_id_str = debug_context(cx).type_map .borrow() .get_unique_type_id_as_string(unique_type_id); - let name = CString::from_slice(struct_type_name.as_bytes()); - let unique_type_id = CString::from_slice(unique_type_id_str.as_bytes()); + let name = CString::new(struct_type_name).unwrap(); + let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap(); let metadata_stub = unsafe { // LLVMDIBuilderCreateStructType() wants an empty array. A null // pointer will lead to hard to trace and debug LLVM assertions @@ -3971,8 +3972,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc ptr::null_mut() }; let namespace_name = token::get_name(name); - let namespace_name = CString::from_slice(namespace_name - .as_bytes()); + let namespace_name = CString::new(namespace_name.as_bytes()).unwrap(); let scope = unsafe { llvm::LLVMDIBuilderCreateNameSpace( DIB(cx), @@ -4020,7 +4020,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc unsafe { // Generate an external declaration. - let buf = CString::from_slice(ident.as_bytes()); + let buf = CString::new(ident.as_bytes()).unwrap(); llvm::LLVMAddGlobal(ccx.llmod(), llty.to_ref(), buf.as_ptr()) } } diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index af90e1ec5c5dd..9e6867d48291a 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -513,7 +513,7 @@ pub fn declare_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) let llalign = llalign_of(ccx, llty); let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc"); debug!("+++ declare_tydesc {} {}", ppaux::ty_to_string(ccx.tcx(), t), name); - let buf = CString::from_slice(name.as_bytes()); + let buf = CString::new(name.clone()).unwrap(); let gvar = unsafe { llvm::LLVMAddGlobal(ccx.llmod(), ccx.tydesc_type().to_ref(), buf.as_ptr()) diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs index e3e4ca62c262f..ad83135a0d46f 100644 --- a/src/librustc_trans/trans/type_.rs +++ b/src/librustc_trans/trans/type_.rs @@ -163,7 +163,7 @@ impl Type { } pub fn named_struct(ccx: &CrateContext, name: &str) -> Type { - let name = CString::from_slice(name.as_bytes()); + let name = CString::new(name).unwrap(); ty!(llvm::LLVMStructCreateNamed(ccx.llcx(), name.as_ptr())) } diff --git a/src/librustdoc/flock.rs b/src/librustdoc/flock.rs index a7cf5eb89187f..eba915af519c8 100644 --- a/src/librustdoc/flock.rs +++ b/src/librustdoc/flock.rs @@ -112,7 +112,7 @@ mod imp { impl Lock { pub fn new(p: &Path) -> Lock { - let buf = CString::from_slice(p.as_vec()); + let buf = CString::from_slice(p.as_vec()).unwrap(); let fd = unsafe { libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT, libc::S_IRWXU) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index c513fe2e8eb3c..3ceaec5f53d82 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -236,7 +236,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { s.push_str(&highlight::highlight(&text, None, Some("rust-example-rendered"))); - let output = CString::from_vec(s.into_bytes()); + let output = CString::from_vec(s.into_bytes()).unwrap(); hoedown_buffer_puts(ob, output.as_ptr()); }) } @@ -293,7 +293,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { format!("{} ", sec) }); - let text = CString::from_vec(text.into_bytes()); + let text = CString::from_vec(text.into_bytes()).unwrap(); unsafe { hoedown_buffer_puts(ob, text.as_ptr()) } } diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index c5dd66630b420..b0fb9c2940351 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -112,7 +112,7 @@ impl DynamicLibrary { // This function should have a lifetime constraint of 'a on // T but that feature is still unimplemented - let raw_string = CString::from_slice(symbol.as_bytes()); + let raw_string = CString::new(symbol).unwrap(); let maybe_symbol_value = dl::check_for_errors_in(|| { dl::symbol(self.handle, raw_string.as_ptr()) }); @@ -187,7 +187,7 @@ mod test { mod dl { use prelude::v1::*; - use ffi::{self, CString}; + use ffi::{CString, CStr}; use str; use libc; use ptr; @@ -206,7 +206,7 @@ mod dl { const LAZY: libc::c_int = 1; unsafe fn open_external(filename: &[u8]) -> *mut u8 { - let s = CString::from_slice(filename); + let s = CString::new(filename).unwrap(); dlopen(s.as_ptr(), LAZY) as *mut u8 } @@ -231,7 +231,7 @@ mod dl { let ret = if ptr::null() == last_error { Ok(result) } else { - let s = ffi::c_str_to_bytes(&last_error); + let s = CStr::from_ptr(last_error).to_bytes(); Err(str::from_utf8(s).unwrap().to_string()) }; diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 45089176cba96..70c14ef197829 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -8,18 +8,25 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; +use error::{Error, FromError}; use fmt; +use io; use iter::IteratorExt; use libc; use mem; +use old_io; use ops::Deref; +use option::Option::{self, Some, None}; +use result::Result::{self, Ok, Err}; use slice::{self, SliceExt}; +use str::StrExt; use string::String; use vec::Vec; -/// A type representing a C-compatible string +/// A type representing an owned C-compatible string /// -/// This type serves the primary purpose of being able to generate a +/// This type serves the primary purpose of being able to safely generate a /// C-compatible string from a Rust byte slice or vector. An instance of this /// type is a static guarantee that the underlying bytes contain no interior 0 /// bytes and the final byte is 0. @@ -44,8 +51,8 @@ use vec::Vec; /// fn my_printer(s: *const libc::c_char); /// } /// -/// let to_print = "Hello, world!"; -/// let c_to_print = CString::from_slice(to_print.as_bytes()); +/// let to_print = b"Hello, world!"; +/// let c_to_print = CString::new(to_print).unwrap(); /// unsafe { /// my_printer(c_to_print.as_ptr()); /// } @@ -53,19 +60,135 @@ use vec::Vec; /// ``` #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] pub struct CString { - inner: Vec, + inner: Vec, +} + +/// Representation of a borrowed C string. +/// +/// This dynamically sized type is only safely constructed via a borrowed +/// version of an instance of `CString`. This type can be constructed from a raw +/// C string as well and represents a C string borrowed from another location. +/// +/// Note that this structure is **not** `repr(C)` and is not recommended to be +/// placed in the signatures of FFI functions. Instead safe wrappers of FFI +/// functions may leverage the unsafe `from_ptr` constructor to provide a safe +/// interface to other consumers. +/// +/// # Examples +/// +/// Inspecting a foreign C string +/// +/// ```no_run +/// extern crate libc; +/// use std::ffi::CStr; +/// +/// extern { fn my_string() -> *const libc::c_char; } +/// +/// fn main() { +/// unsafe { +/// let slice = CStr::from_ptr(my_string()); +/// println!("string length: {}", slice.to_bytes().len()); +/// } +/// } +/// ``` +/// +/// Passing a Rust-originating C string +/// +/// ```no_run +/// extern crate libc; +/// use std::ffi::{CString, CStr}; +/// +/// fn work(data: &CStr) { +/// extern { fn work_with(data: *const libc::c_char); } +/// +/// unsafe { work_with(data.as_ptr()) } +/// } +/// +/// fn main() { +/// let s = CString::from_slice(b"data data data data").unwrap(); +/// work(&s); +/// } +/// ``` +#[derive(Hash)] +pub struct CStr { + inner: [libc::c_char] +} + +/// An error returned from `CString::new` to indicate that a nul byte was found +/// in the vector provided. +#[derive(Clone, PartialEq, Debug)] +pub struct NulError(usize, Vec); + +/// A conversion trait used by the constructor of `CString` for types that can +/// be converted to a vector of bytes. +pub trait IntoBytes { + /// Consumes this container, returning a vector of bytes. + fn into_bytes(self) -> Vec; } impl CString { + /// Create a new C-compatible string from a container of bytes. + /// + /// This method will consume the provided data and use the underlying bytes + /// to construct a new string, ensuring that there is a trailing 0 byte. + /// + /// # Examples + /// + /// ```no_run + /// extern crate libc; + /// use std::ffi::CString; + /// + /// extern { fn puts(s: *const libc::c_char); } + /// + /// fn main() { + /// let to_print = CString::from_slice(b"Hello!").unwrap(); + /// unsafe { + /// puts(to_print.as_ptr()); + /// } + /// } + /// ``` + /// + /// # Errors + /// + /// This function will return an error if the bytes yielded contain an + /// internal 0 byte. The error returned will contain the bytes as well as + /// the position of the nul byte. + pub fn new(t: T) -> Result { + let bytes = t.into_bytes(); + match bytes.iter().position(|x| *x == 0) { + Some(i) => Err(NulError(i, bytes)), + None => Ok(unsafe { CString::from_vec_unchecked(bytes) }), + } + } + /// Create a new C-compatible string from a byte slice. /// /// This method will copy the data of the slice provided into a new /// allocation, ensuring that there is a trailing 0 byte. /// + /// # Examples + /// + /// ```no_run + /// extern crate libc; + /// use std::ffi::CString; + /// + /// extern { fn puts(s: *const libc::c_char); } + /// + /// fn main() { + /// let to_print = CString::from_slice(b"Hello!").unwrap(); + /// unsafe { + /// puts(to_print.as_ptr()); + /// } + /// } + /// ``` + /// /// # Panics /// - /// This function will panic if there are any 0 bytes already in the slice - /// provided. + /// This function will panic if the provided slice contains any + /// interior nul bytes. + #[unstable(feature = "std_misc")] + #[deprecated(since = "1.0.0", reason = "use CString::new instead")] + #[allow(deprecated)] pub fn from_slice(v: &[u8]) -> CString { CString::from_vec(v.to_vec()) } @@ -77,11 +200,15 @@ impl CString { /// /// # Panics /// - /// This function will panic if there are any 0 bytes already in the vector - /// provided. + /// This function will panic if the provided slice contains any + /// interior nul bytes. + #[unstable(feature = "std_misc")] + #[deprecated(since = "1.0.0", reason = "use CString::new instead")] pub fn from_vec(v: Vec) -> CString { - assert!(!v.iter().any(|&x| x == 0)); - unsafe { CString::from_vec_unchecked(v) } + match v.iter().position(|x| *x == 0) { + Some(i) => panic!("null byte found in slice at: {}", i), + None => unsafe { CString::from_vec_unchecked(v) }, + } } /// Create a C-compatible string from a byte vector without checking for @@ -91,31 +218,29 @@ impl CString { /// is made that `v` contains no 0 bytes. pub unsafe fn from_vec_unchecked(mut v: Vec) -> CString { v.push(0); - CString { inner: mem::transmute(v) } + CString { inner: v } } - /// Create a view into this C string which includes the trailing nul - /// terminator at the end of the string. - pub fn as_slice_with_nul(&self) -> &[libc::c_char] { &self.inner } - - /// Similar to the `as_slice` method, but returns a `u8` slice instead of a - /// `libc::c_char` slice. + /// Returns the contents of this `CString` as a slice of bytes. + /// + /// The returned slice does **not** contain the trailing nul separator and + /// it is guaranteet to not have any interior nul bytes. pub fn as_bytes(&self) -> &[u8] { - unsafe { mem::transmute(&**self) } + &self.inner[..self.inner.len() - 1] } - /// Equivalent to `as_slice_with_nul` except that the type returned is a - /// `u8` slice instead of a `libc::c_char` slice. + /// Equivalent to the `as_bytes` function except that the returned slice + /// includes the trailing nul byte. pub fn as_bytes_with_nul(&self) -> &[u8] { - unsafe { mem::transmute(self.as_slice_with_nul()) } + &self.inner } } impl Deref for CString { - type Target = [libc::c_char]; + type Target = CStr; - fn deref(&self) -> &[libc::c_char] { - &self.inner[..(self.inner.len() - 1)] + fn deref(&self) -> &CStr { + unsafe { mem::transmute(self.as_bytes_with_nul()) } } } @@ -126,54 +251,172 @@ impl fmt::Debug for CString { } } -/// Interpret a C string as a byte slice. -/// -/// This function will calculate the length of the C string provided, and it -/// will then return a corresponding slice for the contents of the C string not -/// including the nul terminator. -/// -/// This function will tie the lifetime of the returned slice to the lifetime of -/// the pointer provided. This is done to help prevent the slice from escaping -/// the lifetime of the pointer itself. If a longer lifetime is needed, then -/// `mem::copy_lifetime` should be used. -/// -/// This function is unsafe because there is no guarantee of the validity of the -/// pointer `raw` or a guarantee that a nul terminator will be found. -/// -/// # Example -/// -/// ```no_run -/// # extern crate libc; -/// # fn main() { -/// use std::ffi; -/// use std::str; -/// use libc; -/// -/// extern { -/// fn my_string() -> *const libc::c_char; -/// } -/// -/// unsafe { -/// let to_print = my_string(); -/// let slice = ffi::c_str_to_bytes(&to_print); -/// println!("string returned: {}", str::from_utf8(slice).unwrap()); -/// } -/// # } -/// ``` +impl NulError { + /// Returns the position of the nul byte in the slice that was provided to + /// `CString::from_vec`. + pub fn nul_position(&self) -> usize { self.0 } + + /// Consumes this error, returning the underlying vector of bytes which + /// generated the error in the first place. + pub fn into_vec(self) -> Vec { self.1 } +} + +impl Error for NulError { + fn description(&self) -> &str { "nul byte found in data" } +} + +impl fmt::Display for NulError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "nul byte found in provided data at position: {}", self.0) + } +} + +impl FromError for io::Error { + fn from_error(_: NulError) -> io::Error { + io::Error::new(io::ErrorKind::InvalidInput, + "data provided contains a nul byte", None) + } +} + +impl FromError for old_io::IoError { + fn from_error(_: NulError) -> old_io::IoError { + old_io::IoError { + kind: old_io::IoErrorKind::InvalidInput, + desc: "data provided contains a nul byte", + detail: None + } + } +} + +impl CStr { + /// Cast a raw C string to a safe C string wrapper. + /// + /// This function will cast the provided `ptr` to the `CStr` wrapper which + /// allows inspection and interoperation of non-owned C strings. This method + /// is unsafe for a number of reasons: + /// + /// * There is no guarantee to the validity of `ptr` + /// * The returned lifetime is not guaranteed to be the actual lifetime of + /// `ptr` + /// * There is no guarantee that the memory pointed to by `ptr` contains a + /// valid nul terminator byte at the end of the string. + /// + /// > **Note**: This operation is intended to be a 0-cost cast but it is + /// > currently implemented with an up-front calculation of the length of + /// > the string. This is not guaranteed to always be the case. + /// + /// # Example + /// + /// ```no_run + /// # extern crate libc; + /// # fn main() { + /// use std::ffi::CStr; + /// use std::str; + /// use libc; + /// + /// extern { + /// fn my_string() -> *const libc::c_char; + /// } + /// + /// unsafe { + /// let slice = CStr::from_ptr(my_string()); + /// println!("string returned: {}", + /// str::from_utf8(slice.to_bytes()).unwrap()); + /// } + /// # } + /// ``` + pub unsafe fn from_ptr<'a>(ptr: *const libc::c_char) -> &'a CStr { + let len = libc::strlen(ptr); + mem::transmute(slice::from_raw_parts(ptr, len as usize + 1)) + } + + /// Return the inner pointer to this C string. + /// + /// The returned pointer will be valid for as long as `self` is and points + /// to a continguous region of memory terminated with a 0 byte to represent + /// the end of the string. + pub fn as_ptr(&self) -> *const libc::c_char { + self.inner.as_ptr() + } + + /// Convert this C string to a byte slice. + /// + /// This function will calculate the length of this string (which normally + /// requires a linear amount of work to be done) and then return the + /// resulting slice of `u8` elements. + /// + /// The returned slice will **not** contain the trailing nul that this C + /// string has. + /// + /// > **Note**: This method is currently implemented as a 0-cost cast, but + /// > it is planned to alter its definition in the future to perform the + /// > length calculation whenever this method is called. + pub fn to_bytes(&self) -> &[u8] { + let bytes = self.to_bytes_with_nul(); + &bytes[..bytes.len() - 1] + } + + /// Convert this C string to a byte slice containing the trailing 0 byte. + /// + /// This function is the equivalent of `to_bytes` except that it will retain + /// the trailing nul instead of chopping it off. + /// + /// > **Note**: This method is currently implemented as a 0-cost cast, but + /// > it is planned to alter its definition in the future to perform the + /// > length calculation whenever this method is called. + pub fn to_bytes_with_nul(&self) -> &[u8] { + unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.inner) } + } +} + +impl PartialEq for CStr { + fn eq(&self, other: &CStr) -> bool { + self.to_bytes().eq(&other.to_bytes()) + } +} +impl Eq for CStr {} +impl PartialOrd for CStr { + fn partial_cmp(&self, other: &CStr) -> Option { + self.to_bytes().partial_cmp(&other.to_bytes()) + } +} +impl Ord for CStr { + fn cmp(&self, other: &CStr) -> Ordering { + self.to_bytes().cmp(&other.to_bytes()) + } +} + +/// Deprecated in favor of `CStr` +#[unstable(feature = "std_misc")] +#[deprecated(since = "1.0.0", reason = "use CStr::from_ptr(p).to_bytes() instead")] pub unsafe fn c_str_to_bytes<'a>(raw: &'a *const libc::c_char) -> &'a [u8] { let len = libc::strlen(*raw); slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize) } -/// Interpret a C string as a byte slice with the nul terminator. -/// -/// This function is identical to `from_raw_buf` except that the returned slice -/// will include the nul terminator of the string. -pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char) -> &'a [u8] { +/// Deprecated in favor of `CStr` +#[unstable(feature = "std_misc")] +#[deprecated(since = "1.0.0", + reason = "use CStr::from_ptr(p).to_bytes_with_nul() instead")] +pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char) + -> &'a [u8] { let len = libc::strlen(*raw) + 1; slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize) } +impl<'a> IntoBytes for &'a str { + fn into_bytes(self) -> Vec { self.as_bytes().to_vec() } +} +impl<'a> IntoBytes for &'a [u8] { + fn into_bytes(self) -> Vec { self.to_vec() } +} +impl IntoBytes for String { + fn into_bytes(self) -> Vec { self.into_bytes() } +} +impl IntoBytes for Vec { + fn into_bytes(self) -> Vec { self } +} + #[cfg(test)] mod tests { use prelude::v1::*; @@ -193,21 +436,19 @@ mod tests { #[test] fn simple() { - let s = CString::from_slice(b"1234"); + let s = CString::from_slice(b"1234").unwrap(); assert_eq!(s.as_bytes(), b"1234"); assert_eq!(s.as_bytes_with_nul(), b"1234\0"); - unsafe { - assert_eq!(&*s, - mem::transmute::<_, &[libc::c_char]>(b"1234")); - assert_eq!(s.as_slice_with_nul(), - mem::transmute::<_, &[libc::c_char]>(b"1234\0")); - } } - #[should_fail] #[test] - fn build_with_zero1() { CString::from_slice(b"\0"); } - #[should_fail] #[test] - fn build_with_zero2() { CString::from_vec(vec![0]); } + #[test] + fn build_with_zero1() { + assert!(CString::from_slice(b"\0").is_err()); + } + #[test] + fn build_with_zero2() { + assert!(CString::from_vec(vec![0]).is_err()); + } #[test] fn build_with_zero3() { @@ -219,7 +460,16 @@ mod tests { #[test] fn formatted() { - let s = CString::from_slice(b"12"); + let s = CString::from_slice(b"12").unwrap(); assert_eq!(format!("{:?}", s), "\"12\""); } + + #[test] + fn borrowed() { + unsafe { + let s = CStr::from_ptr(b"12\0".as_ptr() as *const _); + assert_eq!(s.to_bytes(), b"12"); + assert_eq!(s.to_bytes_with_nul(), b"12\0"); + } + } } diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index 07a4f17796c49..1bff6afb77607 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -14,8 +14,10 @@ reason = "module just underwent fairly large reorganization and the dust \ still needs to settle")] -pub use self::c_str::CString; +pub use self::c_str::{CString, CStr, NulError, IntoBytes}; +#[allow(deprecated)] pub use self::c_str::c_str_to_bytes; +#[allow(deprecated)] pub use self::c_str::c_str_to_bytes_with_nul; pub use self::os_str::OsString; diff --git a/src/libstd/old_io/net/pipe.rs b/src/libstd/old_io/net/pipe.rs index 6b32d936c05be..392a253d73366 100644 --- a/src/libstd/old_io/net/pipe.rs +++ b/src/libstd/old_io/net/pipe.rs @@ -55,7 +55,7 @@ impl UnixStream { /// stream.write(&[1, 2, 3]); /// ``` pub fn connect(path: P) -> IoResult { - let path = CString::from_slice(path.container_as_bytes()); + let path = try!(CString::new(path.container_as_bytes())); UnixStreamImp::connect(&path, None) .map(|inner| UnixStream { inner: inner }) } @@ -77,7 +77,7 @@ impl UnixStream { return Err(standard_error(TimedOut)); } - let path = CString::from_slice(path.container_as_bytes()); + let path = try!(CString::new(path.container_as_bytes())); UnixStreamImp::connect(&path, Some(timeout.num_milliseconds() as u64)) .map(|inner| UnixStream { inner: inner }) } @@ -184,7 +184,7 @@ impl UnixListener { /// # } /// ``` pub fn bind(path: P) -> IoResult { - let path = CString::from_slice(path.container_as_bytes()); + let path = try!(CString::new(path.container_as_bytes())); UnixListenerImp::bind(&path) .map(|inner| UnixListener { inner: inner }) } diff --git a/src/libstd/old_io/process.rs b/src/libstd/old_io/process.rs index ea6510c61b76b..c761bf705a81f 100644 --- a/src/libstd/old_io/process.rs +++ b/src/libstd/old_io/process.rs @@ -204,7 +204,7 @@ impl Command { /// otherwise configure the process. pub fn new(program: T) -> Command { Command { - program: CString::from_slice(program.container_as_bytes()), + program: CString::new(program.container_as_bytes()).unwrap(), args: Vec::new(), env: None, cwd: None, @@ -219,14 +219,14 @@ impl Command { /// Add an argument to pass to the program. pub fn arg<'a, T: BytesContainer>(&'a mut self, arg: T) -> &'a mut Command { - self.args.push(CString::from_slice(arg.container_as_bytes())); + self.args.push(CString::new(arg.container_as_bytes()).unwrap()); self } /// Add multiple arguments to pass to the program. pub fn args<'a, T: BytesContainer>(&'a mut self, args: &[T]) -> &'a mut Command { self.args.extend(args.iter().map(|arg| { - CString::from_slice(arg.container_as_bytes()) + CString::new(arg.container_as_bytes()).unwrap() })); self } @@ -239,8 +239,8 @@ impl Command { // if the env is currently just inheriting from the parent's, // materialize the parent's env into a hashtable. self.env = Some(os::env_as_bytes().into_iter().map(|(k, v)| { - (EnvKey(CString::from_slice(&k)), - CString::from_slice(&v)) + (EnvKey(CString::new(k).unwrap()), + CString::new(v).unwrap()) }).collect()); self.env.as_mut().unwrap() } @@ -254,8 +254,8 @@ impl Command { pub fn env<'a, T, U>(&'a mut self, key: T, val: U) -> &'a mut Command where T: BytesContainer, U: BytesContainer { - let key = EnvKey(CString::from_slice(key.container_as_bytes())); - let val = CString::from_slice(val.container_as_bytes()); + let key = EnvKey(CString::new(key.container_as_bytes()).unwrap()); + let val = CString::new(val.container_as_bytes()).unwrap(); self.get_env_map().insert(key, val); self } @@ -263,7 +263,7 @@ impl Command { /// Removes an environment variable mapping. pub fn env_remove<'a, T>(&'a mut self, key: T) -> &'a mut Command where T: BytesContainer { - let key = EnvKey(CString::from_slice(key.container_as_bytes())); + let key = EnvKey(CString::new(key.container_as_bytes()).unwrap()); self.get_env_map().remove(&key); self } @@ -276,15 +276,15 @@ impl Command { -> &'a mut Command where T: BytesContainer, U: BytesContainer { self.env = Some(env.iter().map(|&(ref k, ref v)| { - (EnvKey(CString::from_slice(k.container_as_bytes())), - CString::from_slice(v.container_as_bytes())) + (EnvKey(CString::new(k.container_as_bytes()).unwrap()), + CString::new(v.container_as_bytes()).unwrap()) }).collect()); self } /// Set the working directory for the child process. pub fn cwd<'a>(&'a mut self, dir: &Path) -> &'a mut Command { - self.cwd = Some(CString::from_slice(dir.as_vec())); + self.cwd = Some(CString::new(dir.as_vec()).unwrap()); self } @@ -1226,7 +1226,7 @@ mod tests { cmd.env("path", "foo"); cmd.env("Path", "bar"); let env = &cmd.env.unwrap(); - let val = env.get(&EnvKey(CString::from_slice(b"PATH"))); - assert!(val.unwrap() == &CString::from_slice(b"bar")); + let val = env.get(&EnvKey(CString::new(b"PATH").unwrap())); + assert!(val.unwrap() == &CString::new(b"bar").unwrap()); } } diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs index c2f5133eaf3fe..61f5bd0f01360 100644 --- a/src/libstd/rt/args.rs +++ b/src/libstd/rt/args.rs @@ -49,7 +49,7 @@ mod imp { use libc; use mem; - use ffi; + use ffi::CStr; use sync::{StaticMutex, MUTEX_INIT}; @@ -96,10 +96,11 @@ mod imp { unsafe { mem::transmute(&GLOBAL_ARGS_PTR) } } - unsafe fn load_argc_and_argv(argc: int, argv: *const *const u8) -> Vec> { + unsafe fn load_argc_and_argv(argc: isize, + argv: *const *const u8) -> Vec> { let argv = argv as *const *const libc::c_char; - (0..argc as uint).map(|i| { - ffi::c_str_to_bytes(&*argv.offset(i as int)).to_vec() + (0..argc).map(|i| { + CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec() }).collect() } diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 7325e0a5ac8dd..e2ac5ac24f89e 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -12,8 +12,7 @@ use prelude::v1::*; use self::SocketStatus::*; use self::InAddr::*; -use ffi::CString; -use ffi; +use ffi::{CString, CStr}; use old_io::net::addrinfo; use old_io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr}; use old_io::{IoResult, IoError}; @@ -235,9 +234,15 @@ pub fn get_host_addresses(host: Option<&str>, servname: Option<&str>, assert!(host.is_some() || servname.is_some()); - let c_host = host.map(|x| CString::from_slice(x.as_bytes())); + let c_host = match host { + Some(x) => Some(try!(CString::new(x))), + None => None, + }; let c_host = c_host.as_ref().map(|x| x.as_ptr()).unwrap_or(null()); - let c_serv = servname.map(|x| CString::from_slice(x.as_bytes())); + let c_serv = match servname { + Some(x) => Some(try!(CString::new(x))), + None => None, + }; let c_serv = c_serv.as_ref().map(|x| x.as_ptr()).unwrap_or(null()); let hint = hint.map(|hint| { @@ -325,8 +330,8 @@ pub fn get_address_name(addr: IpAddr) -> Result { } unsafe { - Ok(str::from_utf8(ffi::c_str_to_bytes(&hostbuf.as_ptr())) - .unwrap().to_string()) + let data = CStr::from_ptr(hostbuf.as_ptr()); + Ok(str::from_utf8(data.to_bytes()).unwrap().to_string()) } } diff --git a/src/libstd/sys/common/net2.rs b/src/libstd/sys/common/net2.rs index 5af59ec6d2b14..713f79c5d0814 100644 --- a/src/libstd/sys/common/net2.rs +++ b/src/libstd/sys/common/net2.rs @@ -121,7 +121,7 @@ impl Drop for LookupHost { pub fn lookup_host(host: &str) -> io::Result { init(); - let c_host = CString::from_slice(host.as_bytes()); + let c_host = try!(CString::new(host)); let mut res = 0 as *mut _; unsafe { try!(cvt_gai(getaddrinfo(c_host.as_ptr(), 0 as *const _, 0 as *const _, diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs index 5e512e9261b1d..8b560339f3044 100644 --- a/src/libstd/sys/unix/backtrace.rs +++ b/src/libstd/sys/unix/backtrace.rs @@ -85,7 +85,7 @@ use prelude::v1::*; -use ffi; +use ffi::CStr; use old_io::IoResult; use libc; use mem; @@ -233,7 +233,7 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> { output(w, idx,addr, None) } else { output(w, idx, addr, Some(unsafe { - ffi::c_str_to_bytes(&info.dli_sname) + CStr::from_ptr(info.dli_sname).to_bytes() })) } } @@ -364,7 +364,7 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> { if ret == 0 || data.is_null() { output(w, idx, addr, None) } else { - output(w, idx, addr, Some(unsafe { ffi::c_str_to_bytes(&data) })) + output(w, idx, addr, Some(unsafe { CStr::from_ptr(data).to_bytes() })) } } diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs index bbbe022fbaf61..b8b9dcfb3c689 100644 --- a/src/libstd/sys/unix/ext.rs +++ b/src/libstd/sys/unix/ext.rs @@ -33,7 +33,7 @@ use prelude::v1::*; -use ffi::{CString, OsStr, OsString}; +use ffi::{CString, NulError, OsStr, OsString}; use fs::{self, Permissions, OpenOptions}; use net; use mem; @@ -155,7 +155,7 @@ pub trait OsStrExt { fn as_bytes(&self) -> &[u8]; /// Convert the `OsStr` slice into a `CString`. - fn to_cstring(&self) -> CString; + fn to_cstring(&self) -> Result; } impl OsStrExt for OsStr { @@ -166,8 +166,8 @@ impl OsStrExt for OsStr { &self.as_inner().inner } - fn to_cstring(&self) -> CString { - CString::from_slice(self.as_bytes()) + fn to_cstring(&self) -> Result { + CString::new(self.as_bytes()) } } @@ -249,5 +249,7 @@ impl ExitStatusExt for process::ExitStatus { /// Includes all extension traits, and some important type definitions. pub mod prelude { #[doc(no_inline)] - pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt, CommandExt, ExitStatusExt}; + pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt}; + #[doc(no_inline)] + pub use super::{CommandExt, ExitStatusExt}; } diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 0ee2b5b68090e..5c847002d2394 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -12,7 +12,7 @@ use prelude::v1::*; -use ffi::{self, CString}; +use ffi::{CString, CStr}; use old_io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode}; use old_io::{IoResult, FileStat, SeekStyle}; use old_io::{Read, Truncate, SeekCur, SeekSet, ReadWrite, SeekEnd, Append}; @@ -151,8 +151,8 @@ impl Drop for FileDesc { } } -fn cstr(path: &Path) -> CString { - CString::from_slice(path.as_vec()) +fn cstr(path: &Path) -> IoResult { + Ok(try!(CString::new(path.as_vec()))) } pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult { @@ -170,7 +170,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult { libc::S_IRUSR | libc::S_IWUSR), }; - let path = cstr(path); + let path = try!(cstr(path)); match retry(|| unsafe { libc::open(path.as_ptr(), flags, mode) }) { -1 => Err(super::last_error()), fd => Ok(FileDesc::new(fd, true)), @@ -178,7 +178,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult { } pub fn mkdir(p: &Path, mode: uint) -> IoResult<()> { - let p = cstr(p); + let p = try!(cstr(p)); mkerr_libc(unsafe { libc::mkdir(p.as_ptr(), mode as libc::mode_t) }) } @@ -203,7 +203,7 @@ pub fn readdir(p: &Path) -> IoResult> { let mut buf = Vec::::with_capacity(size as uint); let ptr = buf.as_mut_ptr() as *mut dirent_t; - let p = CString::from_slice(p.as_vec()); + let p = try!(CString::new(p.as_vec())); let dir_ptr = unsafe {opendir(p.as_ptr())}; if dir_ptr as uint != 0 { @@ -212,7 +212,7 @@ pub fn readdir(p: &Path) -> IoResult> { while unsafe { readdir_r(dir_ptr, ptr, &mut entry_ptr) == 0 } { if entry_ptr.is_null() { break } paths.push(unsafe { - Path::new(ffi::c_str_to_bytes(&rust_list_dir_val(entry_ptr))) + Path::new(CStr::from_ptr(rust_list_dir_val(entry_ptr)).to_bytes()) }); } assert_eq!(unsafe { closedir(dir_ptr) }, 0); @@ -223,39 +223,39 @@ pub fn readdir(p: &Path) -> IoResult> { } pub fn unlink(p: &Path) -> IoResult<()> { - let p = cstr(p); + let p = try!(cstr(p)); mkerr_libc(unsafe { libc::unlink(p.as_ptr()) }) } pub fn rename(old: &Path, new: &Path) -> IoResult<()> { - let old = cstr(old); - let new = cstr(new); + let old = try!(cstr(old)); + let new = try!(cstr(new)); mkerr_libc(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) }) } pub fn chmod(p: &Path, mode: uint) -> IoResult<()> { - let p = cstr(p); + let p = try!(cstr(p)); mkerr_libc(retry(|| unsafe { libc::chmod(p.as_ptr(), mode as libc::mode_t) })) } pub fn rmdir(p: &Path) -> IoResult<()> { - let p = cstr(p); + let p = try!(cstr(p)); mkerr_libc(unsafe { libc::rmdir(p.as_ptr()) }) } pub fn chown(p: &Path, uid: int, gid: int) -> IoResult<()> { - let p = cstr(p); + let p = try!(cstr(p)); mkerr_libc(retry(|| unsafe { libc::chown(p.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })) } pub fn readlink(p: &Path) -> IoResult { - let c_path = cstr(p); + let c_path = try!(cstr(p)); let p = c_path.as_ptr(); let mut len = unsafe { libc::pathconf(p as *mut _, libc::_PC_NAME_MAX) }; if len == -1 { @@ -276,14 +276,14 @@ pub fn readlink(p: &Path) -> IoResult { } pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> { - let src = cstr(src); - let dst = cstr(dst); + let src = try!(cstr(src)); + let dst = try!(cstr(dst)); mkerr_libc(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) }) } pub fn link(src: &Path, dst: &Path) -> IoResult<()> { - let src = cstr(src); - let dst = cstr(dst); + let src = try!(cstr(src)); + let dst = try!(cstr(dst)); mkerr_libc(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) }) } @@ -331,7 +331,7 @@ fn mkstat(stat: &libc::stat) -> FileStat { } pub fn stat(p: &Path) -> IoResult { - let p = cstr(p); + let p = try!(cstr(p)); let mut stat: libc::stat = unsafe { mem::zeroed() }; match unsafe { libc::stat(p.as_ptr(), &mut stat) } { 0 => Ok(mkstat(&stat)), @@ -340,7 +340,7 @@ pub fn stat(p: &Path) -> IoResult { } pub fn lstat(p: &Path) -> IoResult { - let p = cstr(p); + let p = try!(cstr(p)); let mut stat: libc::stat = unsafe { mem::zeroed() }; match unsafe { libc::lstat(p.as_ptr(), &mut stat) } { 0 => Ok(mkstat(&stat)), @@ -349,7 +349,7 @@ pub fn lstat(p: &Path) -> IoResult { } pub fn utime(p: &Path, atime: u64, mtime: u64) -> IoResult<()> { - let p = cstr(p); + let p = try!(cstr(p)); let buf = libc::utimbuf { actime: (atime / 1000) as libc::time_t, modtime: (mtime / 1000) as libc::time_t, diff --git a/src/libstd/sys/unix/fs2.rs b/src/libstd/sys/unix/fs2.rs index e5904b074bcb9..92a47c6c3850d 100644 --- a/src/libstd/sys/unix/fs2.rs +++ b/src/libstd/sys/unix/fs2.rs @@ -12,7 +12,7 @@ use core::prelude::*; use io::prelude::*; use os::unix::prelude::*; -use ffi::{self, CString, OsString, AsOsStr, OsStr}; +use ffi::{CString, CStr, OsString, AsOsStr, OsStr}; use io::{self, Error, Seek, SeekFrom}; use libc::{self, c_int, c_void, size_t, off_t, c_char, mode_t}; use mem; @@ -147,8 +147,7 @@ impl DirEntry { fn rust_list_dir_val(ptr: *mut libc::dirent_t) -> *const c_char; } unsafe { - let ptr = rust_list_dir_val(self.dirent); - ffi::c_str_to_bytes(mem::copy_lifetime(self, &ptr)) + CStr::from_ptr(rust_list_dir_val(self.dirent)).to_bytes() } } } @@ -204,7 +203,7 @@ impl File { (true, false) | (false, false) => libc::O_RDONLY, }; - let path = cstr(path); + let path = try!(cstr(path)); let fd = try!(cvt_r(|| unsafe { libc::open(path.as_ptr(), flags, opts.mode) })); @@ -268,19 +267,20 @@ impl File { pub fn fd(&self) -> &FileDesc { &self.0 } } -fn cstr(path: &Path) -> CString { - CString::from_slice(path.as_os_str().as_bytes()) +fn cstr(path: &Path) -> io::Result { + let cstring = try!(path.as_os_str().to_cstring()); + Ok(cstring) } pub fn mkdir(p: &Path) -> io::Result<()> { - let p = cstr(p); + let p = try!(cstr(p)); try!(cvt(unsafe { libc::mkdir(p.as_ptr(), 0o777) })); Ok(()) } pub fn readdir(p: &Path) -> io::Result { let root = Rc::new(p.to_path_buf()); - let p = cstr(p); + let p = try!(cstr(p)); unsafe { let ptr = libc::opendir(p.as_ptr()); if ptr.is_null() { @@ -292,32 +292,32 @@ pub fn readdir(p: &Path) -> io::Result { } pub fn unlink(p: &Path) -> io::Result<()> { - let p = cstr(p); + let p = try!(cstr(p)); try!(cvt(unsafe { libc::unlink(p.as_ptr()) })); Ok(()) } pub fn rename(old: &Path, new: &Path) -> io::Result<()> { - let old = cstr(old); - let new = cstr(new); + let old = try!(cstr(old)); + let new = try!(cstr(new)); try!(cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) })); Ok(()) } pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { - let p = cstr(p); + let p = try!(cstr(p)); try!(cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) })); Ok(()) } pub fn rmdir(p: &Path) -> io::Result<()> { - let p = cstr(p); + let p = try!(cstr(p)); try!(cvt(unsafe { libc::rmdir(p.as_ptr()) })); Ok(()) } pub fn chown(p: &Path, uid: isize, gid: isize) -> io::Result<()> { - let p = cstr(p); + let p = try!(cstr(p)); try!(cvt_r(|| unsafe { libc::chown(p.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) })); @@ -325,7 +325,7 @@ pub fn chown(p: &Path, uid: isize, gid: isize) -> io::Result<()> { } pub fn readlink(p: &Path) -> io::Result { - let c_path = cstr(p); + let c_path = try!(cstr(p)); let p = c_path.as_ptr(); let mut len = unsafe { libc::pathconf(p as *mut _, libc::_PC_NAME_MAX) }; if len < 0 { @@ -343,35 +343,35 @@ pub fn readlink(p: &Path) -> io::Result { } pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> { - let src = cstr(src); - let dst = cstr(dst); + let src = try!(cstr(src)); + let dst = try!(cstr(dst)); try!(cvt(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) })); Ok(()) } pub fn link(src: &Path, dst: &Path) -> io::Result<()> { - let src = cstr(src); - let dst = cstr(dst); + let src = try!(cstr(src)); + let dst = try!(cstr(dst)); try!(cvt(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })); Ok(()) } pub fn stat(p: &Path) -> io::Result { - let p = cstr(p); + let p = try!(cstr(p)); let mut stat: libc::stat = unsafe { mem::zeroed() }; try!(cvt(unsafe { libc::stat(p.as_ptr(), &mut stat) })); Ok(FileAttr { stat: stat }) } pub fn lstat(p: &Path) -> io::Result { - let p = cstr(p); + let p = try!(cstr(p)); let mut stat: libc::stat = unsafe { mem::zeroed() }; try!(cvt(unsafe { libc::lstat(p.as_ptr(), &mut stat) })); Ok(FileAttr { stat: stat }) } pub fn utimes(p: &Path, atime: u64, mtime: u64) -> io::Result<()> { - let p = cstr(p); + let p = try!(cstr(p)); let buf = [super::ms_to_timeval(atime), super::ms_to_timeval(mtime)]; try!(cvt(unsafe { c::utimes(p.as_ptr(), buf.as_ptr()) })); Ok(()) diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 850189140d1eb..b79ad7031fa48 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -17,7 +17,7 @@ use prelude::v1::*; -use ffi; +use ffi::CStr; use io::{self, ErrorKind}; use libc; use num::{Int, SignedInt}; @@ -91,7 +91,8 @@ pub fn last_gai_error(s: libc::c_int) -> IoError { let mut err = decode_error(s); err.detail = Some(unsafe { - str::from_utf8(ffi::c_str_to_bytes(&gai_strerror(s))).unwrap().to_string() + let data = CStr::from_ptr(gai_strerror(s)); + str::from_utf8(data.to_bytes()).unwrap().to_string() }); err } diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index 54aec7cf4b193..83b6a14b78d95 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -10,7 +10,7 @@ use prelude::v1::*; -use ffi; +use ffi::CStr; use io; use libc::{self, c_int, size_t}; use str; @@ -31,7 +31,7 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> { if err == 0 { return Ok(()) } let detail = unsafe { - str::from_utf8(ffi::c_str_to_bytes(&c::gai_strerror(err))).unwrap() + str::from_utf8(CStr::from_ptr(c::gai_strerror(err)).to_bytes()).unwrap() .to_string() }; Err(io::Error::new(io::ErrorKind::Other, diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index df03841276e9e..ad56555997ff8 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -14,7 +14,7 @@ use prelude::v1::*; use os::unix::*; use error::Error as StdError; -use ffi::{self, CString, OsString, OsStr, AsOsStr}; +use ffi::{CString, CStr, OsString, OsStr, AsOsStr}; use fmt; use iter; use libc::{self, c_int, c_char, c_void}; @@ -88,7 +88,7 @@ pub fn error_string(errno: i32) -> String { } let p = p as *const _; - str::from_utf8(ffi::c_str_to_bytes(&p)).unwrap().to_string() + str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_string() } } @@ -98,13 +98,13 @@ pub fn getcwd() -> IoResult { if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() { Err(IoError::last_error()) } else { - Ok(Path::new(ffi::c_str_to_bytes(&buf.as_ptr()))) + Ok(Path::new(CStr::from_ptr(buf.as_ptr()).to_bytes())) } } } pub fn chdir(p: &Path) -> IoResult<()> { - let p = CString::from_slice(p.as_vec()); + let p = CString::new(p.as_vec()).unwrap(); unsafe { match libc::chdir(p.as_ptr()) == (0 as c_int) { true => Ok(()), @@ -211,7 +211,7 @@ pub fn current_exe() -> IoResult { if v.is_null() { Err(IoError::last_error()) } else { - Ok(Path::new(ffi::c_str_to_bytes(&v).to_vec())) + Ok(Path::new(CStr::from_ptr(&v).to_bytes().to_vec())) } } } @@ -266,7 +266,7 @@ pub fn args() -> Args { let (argc, argv) = (*_NSGetArgc() as isize, *_NSGetArgv() as *const *const c_char); range(0, argc as isize).map(|i| { - let bytes = ffi::c_str_to_bytes(&*argv.offset(i)).to_vec(); + let bytes = CStr::from_ptr(&*argv.offset(i)).to_bytes().to_vec(); OsStringExt::from_vec(bytes) }).collect::>() }; @@ -324,7 +324,7 @@ pub fn args() -> Args { let tmp = objc_msgSend(args, object_at_sel, i); let utf_c_str: *const libc::c_char = mem::transmute(objc_msgSend(tmp, utf8_sel)); - let bytes = ffi::c_str_to_bytes(&utf_c_str); + let bytes = CStr::from_ptr(utf_c_str).to_bytes(); res.push(OsString::from_str(str::from_utf8(bytes).unwrap())) } } @@ -380,7 +380,7 @@ pub fn env() -> Env { } let mut result = Vec::new(); while *environ != ptr::null() { - result.push(parse(ffi::c_str_to_bytes(&*environ))); + result.push(parse(CStr::from_ptr(*environ).to_bytes())); environ = environ.offset(1); } Env { iter: result.into_iter(), _dont_send_or_sync_me: 0 as *mut _ } @@ -397,20 +397,20 @@ pub fn env() -> Env { pub fn getenv(k: &OsStr) -> Option { unsafe { - let s = CString::from_slice(k.as_bytes()); + let s = k.to_cstring().unwrap(); let s = libc::getenv(s.as_ptr()) as *const _; if s.is_null() { None } else { - Some(OsStringExt::from_vec(ffi::c_str_to_bytes(&s).to_vec())) + Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec())) } } } pub fn setenv(k: &OsStr, v: &OsStr) { unsafe { - let k = CString::from_slice(k.as_bytes()); - let v = CString::from_slice(v.as_bytes()); + let k = k.to_cstring().unwrap(); + let v = v.to_cstring().unwrap(); if libc::funcs::posix01::unistd::setenv(k.as_ptr(), v.as_ptr(), 1) != 0 { panic!("failed setenv: {}", IoError::last_error()); } @@ -419,7 +419,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) { pub fn unsetenv(n: &OsStr) { unsafe { - let nbuf = CString::from_slice(n.as_bytes()); + let nbuf = n.to_cstring().unwrap(); if libc::funcs::posix01::unistd::unsetenv(nbuf.as_ptr()) != 0 { panic!("failed unsetenv: {}", IoError::last_error()); } @@ -480,7 +480,7 @@ pub fn home_dir() -> Option { _ => return None } let ptr = passwd.pw_dir as *const _; - let bytes = ffi::c_str_to_bytes(&ptr).to_vec(); + let bytes = CStr::from_ptr(ptr).to_bytes().to_vec(); return Some(OsStringExt::from_vec(bytes)) } } diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 45d5b1506c3aa..3c9cdc65975f6 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -38,7 +38,7 @@ fn addr_to_sockaddr_un(addr: &CString, mem::size_of::()); let s = unsafe { &mut *(storage as *mut _ as *mut libc::sockaddr_un) }; - let len = addr.len(); + let len = addr.as_bytes().len(); if len > s.sun_path.len() - 1 { return Err(IoError { kind: old_io::InvalidInput, @@ -47,8 +47,8 @@ fn addr_to_sockaddr_un(addr: &CString, }) } s.sun_family = libc::AF_UNIX as libc::sa_family_t; - for (slot, value) in s.sun_path.iter_mut().zip(addr.iter()) { - *slot = *value; + for (slot, value) in s.sun_path.iter_mut().zip(addr.as_bytes().iter()) { + *slot = *value as libc::c_char; } // count the null terminator diff --git a/src/libstd/sys/unix/process2.rs b/src/libstd/sys/unix/process2.rs index 5e2c207f3756a..0e78efa209683 100644 --- a/src/libstd/sys/unix/process2.rs +++ b/src/libstd/sys/unix/process2.rs @@ -46,7 +46,7 @@ pub struct Command { impl Command { pub fn new(program: &OsStr) -> Command { Command { - program: program.to_cstring(), + program: program.to_cstring().unwrap(), args: Vec::new(), env: None, cwd: None, @@ -57,10 +57,10 @@ impl Command { } pub fn arg(&mut self, arg: &OsStr) { - self.args.push(arg.to_cstring()) + self.args.push(arg.to_cstring().unwrap()) } pub fn args<'a, I: Iterator>(&mut self, args: I) { - self.args.extend(args.map(OsStrExt::to_cstring)) + self.args.extend(args.map(|s| OsStrExt::to_cstring(s).unwrap())) } fn init_env_map(&mut self) { if self.env.is_none() { @@ -79,7 +79,7 @@ impl Command { self.env = Some(HashMap::new()) } pub fn cwd(&mut self, dir: &OsStr) { - self.cwd = Some(dir.to_cstring()) + self.cwd = Some(dir.to_cstring().unwrap()) } } diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 82c52471d1097..c90ba7645feb4 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -237,7 +237,7 @@ pub unsafe fn create(stack: uint, p: Thunk) -> io::Result { pub unsafe fn set_name(name: &str) { // pthread_setname_np() since glibc 2.12 // availability autodetected via weak linkage - let cname = CString::from_slice(name.as_bytes()); + let cname = CString::new(name).unwrap(); type F = unsafe extern "C" fn(libc::pthread_t, *const libc::c_char) -> libc::c_int; extern { #[linkage = "extern_weak"] @@ -255,14 +255,14 @@ pub unsafe fn set_name(name: &str) { target_os = "openbsd"))] pub unsafe fn set_name(name: &str) { // pthread_set_name_np() since almost forever on all BSDs - let cname = CString::from_slice(name.as_bytes()); + let cname = CString::new(name).unwrap(); pthread_set_name_np(pthread_self(), cname.as_ptr()); } #[cfg(any(target_os = "macos", target_os = "ios"))] pub unsafe fn set_name(name: &str) { // pthread_setname_np() since OS X 10.6 and iOS 3.2 - let cname = CString::from_slice(name.as_bytes()); + let cname = CString::new(name).unwrap(); pthread_setname_np(cname.as_ptr()); } diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 83a4d938bb5d5..b7a758a00d55d 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -618,22 +618,25 @@ fn print_macro_backtrace(w: &mut EmitterWriter, cm: &codemap::CodeMap, sp: Span) -> old_io::IoResult<()> { - let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| match expn_info { - Some(ei) => { - let ss = ei.callee.span.map_or(String::new(), |span| cm.span_to_string(span)); - let (pre, post) = match ei.callee.format { - codemap::MacroAttribute => ("#[", "]"), - codemap::MacroBang => ("", "!") - }; - try!(print_diagnostic(w, &ss[], Note, - &format!("in expansion of {}{}{}", pre, - ei.callee.name, - post)[], None)); - let ss = cm.span_to_string(ei.call_site); - try!(print_diagnostic(w, &ss[], Note, "expansion site", None)); - Ok(Some(ei.call_site)) - } - None => Ok(None) + let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| -> old_io::IoResult<_> { + match expn_info { + Some(ei) => { + let ss = ei.callee.span.map_or(String::new(), + |span| cm.span_to_string(span)); + let (pre, post) = match ei.callee.format { + codemap::MacroAttribute => ("#[", "]"), + codemap::MacroBang => ("", "!") + }; + try!(print_diagnostic(w, &ss[], Note, + &format!("in expansion of {}{}{}", pre, + ei.callee.name, + post)[], None)); + let ss = cm.span_to_string(ei.call_site); + try!(print_diagnostic(w, &ss[], Note, "expansion site", None)); + Ok(Some(ei.call_site)) + } + None => Ok(None) + } })); cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site)) } diff --git a/src/test/run-pass/c-stack-returning-int64.rs b/src/test/run-pass/c-stack-returning-int64.rs index 22c322b86c979..d18a3055b9c81 100644 --- a/src/test/run-pass/c-stack-returning-int64.rs +++ b/src/test/run-pass/c-stack-returning-int64.rs @@ -24,12 +24,12 @@ mod mlibc { } fn atol(s: String) -> int { - let c = CString::from_slice(s.as_bytes()); + let c = CString::from_slice(s.as_bytes()).unwrap(); unsafe { mlibc::atol(c.as_ptr()) as int } } fn atoll(s: String) -> i64 { - let c = CString::from_slice(s.as_bytes()); + let c = CString::from_slice(s.as_bytes()).unwrap(); unsafe { mlibc::atoll(c.as_ptr()) as i64 } } diff --git a/src/test/run-pass/foreign-fn-linkname.rs b/src/test/run-pass/foreign-fn-linkname.rs index dff1a1eaa0473..25d0cbbcdb6d3 100644 --- a/src/test/run-pass/foreign-fn-linkname.rs +++ b/src/test/run-pass/foreign-fn-linkname.rs @@ -24,7 +24,7 @@ mod mlibc { fn strlen(str: String) -> uint { // C string is terminated with a zero - let s = CString::from_slice(str.as_bytes()); + let s = CString::from_slice(str.as_bytes()).unwrap(); unsafe { mlibc::my_strlen(s.as_ptr()) as uint } diff --git a/src/test/run-pass/rename-directory.rs b/src/test/run-pass/rename-directory.rs index 12e4f27a64f21..1282720d4cb36 100644 --- a/src/test/run-pass/rename-directory.rs +++ b/src/test/run-pass/rename-directory.rs @@ -31,12 +31,12 @@ fn rename_directory() { let test_file = &old_path.join("temp.txt"); /* Write the temp input file */ - let fromp = CString::from_slice(test_file.as_vec()); - let modebuf = CString::from_slice(b"w+b"); + let fromp = CString::from_slice(test_file.as_vec()).unwrap(); + let modebuf = CString::from_slice(b"w+b").unwrap(); let ostream = libc::fopen(fromp.as_ptr(), modebuf.as_ptr()); assert!((ostream as uint != 0u)); let s = "hello".to_string(); - let buf = CString::from_slice(b"hello"); + let buf = CString::from_slice(b"hello").unwrap(); let write_len = libc::fwrite(buf.as_ptr() as *mut _, 1u as libc::size_t, (s.len() + 1u) as libc::size_t, diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs index a729fedb27157..85f6ef0ddcd1b 100644 --- a/src/test/run-pass/variadic-ffi.rs +++ b/src/test/run-pass/variadic-ffi.rs @@ -29,11 +29,11 @@ pub fn main() { unsafe { // Call with just the named parameter - let c = CString::from_slice(b"Hello World\n"); + let c = CString::from_slice(b"Hello World\n").unwrap(); check("Hello World\n", |s| sprintf(s, c.as_ptr())); // Call with variable number of arguments - let c = CString::from_slice(b"%d %f %c %s\n"); + let c = CString::from_slice(b"%d %f %c %s\n").unwrap(); check("42 42.500000 a %d %f %c %s\n\n", |s| { sprintf(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr()); }); @@ -44,11 +44,11 @@ pub fn main() { // A function that takes a function pointer unsafe fn call(p: unsafe extern fn(*mut c_char, *const c_char, ...) -> c_int) { // Call with just the named parameter - let c = CString::from_slice(b"Hello World\n"); + let c = CString::from_slice(b"Hello World\n").unwrap(); check("Hello World\n", |s| sprintf(s, c.as_ptr())); // Call with variable number of arguments - let c = CString::from_slice(b"%d %f %c %s\n"); + let c = CString::from_slice(b"%d %f %c %s\n").unwrap(); check("42 42.500000 a %d %f %c %s\n\n", |s| { sprintf(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr()); }); From 74199c24d0c09d5096eba1c1da7ce2d85a207d4b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 18 Feb 2015 17:30:02 -0500 Subject: [PATCH 62/76] Try to write some basic docs. --- src/librustc/middle/infer/bivariate.rs | 17 +++++++++++++++++ src/librustc/middle/infer/sub.rs | 1 - src/librustc/middle/traits/select.rs | 5 +++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/infer/bivariate.rs b/src/librustc/middle/infer/bivariate.rs index 0589aa03014ad..93c80fb754f71 100644 --- a/src/librustc/middle/infer/bivariate.rs +++ b/src/librustc/middle/infer/bivariate.rs @@ -8,6 +8,23 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! Applies the "bivariance relationship" to two types and/or regions. +//! If (A,B) are bivariant then either A <: B or B <: A. It occurs +//! when type/lifetime parameters are unconstrained. Usually this is +//! an error, but we permit it in the specific case where a type +//! parameter is constrained in a where-clause via an associated type. +//! +//! There are several ways one could implement bivariance. You could +//! just do nothing at all, for example, or you could fully verify +//! that one of the two subtyping relationships hold. We choose to +//! thread a middle line: we relate types up to regions, but ignore +//! all region relationships. +//! +//! At one point, handling bivariance in this fashion was necessary +//! for inference, but I'm actually not sure if that is true anymore. +//! In particular, it might be enough to say (A,B) are bivariant for +//! all (A,B). + use middle::ty::{BuiltinBounds}; use middle::ty::{self, Ty}; use middle::ty::TyVar; diff --git a/src/librustc/middle/infer/sub.rs b/src/librustc/middle/infer/sub.rs index bfe5ba4c4c5d2..33da3092b2a25 100644 --- a/src/librustc/middle/infer/sub.rs +++ b/src/librustc/middle/infer/sub.rs @@ -39,7 +39,6 @@ impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> { fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> { - // Once we're equating, it doesn't matter what the variance is. match v { ty::Invariant => self.equate().tys(a, b), ty::Covariant => self.tys(a, b), diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index ac8f7783eb82b..2411bb17649b5 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -803,8 +803,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ambiguous: false }; - // Check for the `PhantomFn` trait. This is really just a special annotation that - // *always* be considered to match, no matter what the type parameters etc. + // Check for the `PhantomFn` trait. This is really just a + // special annotation that is *always* considered to match, no + // matter what the type parameters are etc. if self.tcx().lang_items.phantom_fn() == Some(obligation.predicate.def_id()) { candidates.vec.push(PhantomFnCandidate); return Ok(candidates); From f5491e63b4a4389aded637b872b7e02180b9585b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 18 Feb 2015 17:30:14 -0500 Subject: [PATCH 63/76] Stabilize Send/Sync. --- src/libcore/marker.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index c97b1713abc57..dc792a3f47f60 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -41,8 +41,7 @@ pub unsafe trait Send: 'static { // empty. } /// Types able to be transferred across thread boundaries. -#[unstable(feature = "core", - reason = "will be overhauled with new lifetime rules; see RFC 458")] +#[stable(feature = "rust1", since = "1.0.0")] #[lang="send"] #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"] #[cfg(not(stage0))] @@ -208,8 +207,7 @@ pub trait Copy : MarkerTrait { /// around the value(s) which can be mutated when behind a `&` /// reference; not doing this is undefined behaviour (for example, /// `transmute`-ing from `&T` to `&mut T` is illegal). -#[unstable(feature = "core", - reason = "will be overhauled with new lifetime rules; see RFC 458")] +#[stable(feature = "rust1", since = "1.0.0")] #[lang="sync"] #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"] pub unsafe trait Sync : MarkerTrait { From cc61f9c1d5baa29209b29a51cb9c553dcb2fb725 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 18 Feb 2015 17:31:26 -0500 Subject: [PATCH 64/76] Minor unused imports etc. --- src/libstd/path.rs | 1 - src/libstd/thread.rs | 2 +- src/libterm/lib.rs | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index e3650537a63ad..1d992668900f0 100755 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -143,7 +143,6 @@ mod platform { use super::Prefix; use core::prelude::*; use ffi::OsStr; - use std::marker::PhantomData; #[inline] pub fn is_sep_byte(b: u8) -> bool { diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index 2d825a0f4550b..3653e7e31d5c6 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -153,7 +153,7 @@ use any::Any; use cell::UnsafeCell; use fmt; use io; -use marker::{PhantomData, Send, Sync}; +use marker::PhantomData; use old_io::stdio; use rt::{self, unwind}; use sync::{Mutex, Condvar, Arc}; diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 304f370a1993e..5418533aff1d9 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -50,7 +50,6 @@ html_playground_url = "http://play.rust-lang.org/")] #![deny(missing_docs)] -#![feature(core)] #![feature(box_syntax)] #![feature(collections)] #![feature(int_uint)] From 9f8b9d6847ab02f7f1c28c84988ceae4c0a10f26 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 18 Feb 2015 17:31:42 -0500 Subject: [PATCH 65/76] Update tests to use #[feature(rustc_attrs)] --- src/test/compile-fail/variance-trait-bounds.rs | 1 + src/test/compile-fail/variance-types-bounds.rs | 2 ++ src/test/compile-fail/variance-types.rs | 1 + src/test/compile-fail/variance-use-contravariant-struct-1.rs | 2 ++ src/test/compile-fail/variance-use-contravariant-struct-2.rs | 1 + src/test/compile-fail/variance-use-covariant-struct-2.rs | 1 + src/test/compile-fail/variance-use-invariant-struct-1.rs | 2 ++ 7 files changed, 10 insertions(+) diff --git a/src/test/compile-fail/variance-trait-bounds.rs b/src/test/compile-fail/variance-trait-bounds.rs index 661979479237e..88b50058b6580 100644 --- a/src/test/compile-fail/variance-trait-bounds.rs +++ b/src/test/compile-fail/variance-trait-bounds.rs @@ -10,6 +10,7 @@ #![deny(bivariance)] #![allow(dead_code)] +#![feature(rustc_attrs)] // Check that bounds on type parameters (other than `Self`) do not // influence variance. diff --git a/src/test/compile-fail/variance-types-bounds.rs b/src/test/compile-fail/variance-types-bounds.rs index c60649878feaf..d53e4cd76105b 100644 --- a/src/test/compile-fail/variance-types-bounds.rs +++ b/src/test/compile-fail/variance-types-bounds.rs @@ -11,6 +11,8 @@ // Test that we correctly infer variance for type parameters in // various types and traits. +#![feature(rustc_attrs)] + #[rustc_variance] struct TestImm { //~ ERROR types=[[+, +];[];[]] x: A, diff --git a/src/test/compile-fail/variance-types.rs b/src/test/compile-fail/variance-types.rs index 6f6dd72769283..e407ebe345a5b 100644 --- a/src/test/compile-fail/variance-types.rs +++ b/src/test/compile-fail/variance-types.rs @@ -10,6 +10,7 @@ #![deny(bivariance)] #![allow(dead_code)] +#![feature(rustc_attrs)] use std::cell::Cell; diff --git a/src/test/compile-fail/variance-use-contravariant-struct-1.rs b/src/test/compile-fail/variance-use-contravariant-struct-1.rs index 21a9e2477df7c..d2fd2978750e7 100644 --- a/src/test/compile-fail/variance-use-contravariant-struct-1.rs +++ b/src/test/compile-fail/variance-use-contravariant-struct-1.rs @@ -11,6 +11,8 @@ // Test various uses of structs with distint variances to make sure // they permit lifetimes to be approximated as expected. +#![feature(rustc_attrs)] + struct SomeStruct(fn(T)); fn foo<'min,'max>(v: SomeStruct<&'max ()>) diff --git a/src/test/compile-fail/variance-use-contravariant-struct-2.rs b/src/test/compile-fail/variance-use-contravariant-struct-2.rs index dd80ac91683b4..b38fd0e9ffcc6 100644 --- a/src/test/compile-fail/variance-use-contravariant-struct-2.rs +++ b/src/test/compile-fail/variance-use-contravariant-struct-2.rs @@ -12,6 +12,7 @@ // they permit lifetimes to be approximated as expected. #![allow(dead_code)] +#![feature(rustc_attrs)] struct SomeStruct(fn(T)); diff --git a/src/test/compile-fail/variance-use-covariant-struct-2.rs b/src/test/compile-fail/variance-use-covariant-struct-2.rs index f85f7bb6a384f..d8e1a5f5f1c54 100644 --- a/src/test/compile-fail/variance-use-covariant-struct-2.rs +++ b/src/test/compile-fail/variance-use-covariant-struct-2.rs @@ -12,6 +12,7 @@ // be shortened. #![allow(dead_code)] +#![feature(rustc_attrs)] struct SomeStruct(T); diff --git a/src/test/compile-fail/variance-use-invariant-struct-1.rs b/src/test/compile-fail/variance-use-invariant-struct-1.rs index b544ef00fc0a3..c89436b20949c 100644 --- a/src/test/compile-fail/variance-use-invariant-struct-1.rs +++ b/src/test/compile-fail/variance-use-invariant-struct-1.rs @@ -11,6 +11,8 @@ // Test various uses of structs with distint variances to make sure // they permit lifetimes to be approximated as expected. +#![feature(rustc_attrs)] + struct SomeStruct(*mut T); fn foo<'min,'max>(v: SomeStruct<&'max ()>) From 64cd30e0cacb6b509f9368004afb0b6bde7a5143 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 18 Feb 2015 14:47:14 -0500 Subject: [PATCH 66/76] Declare `&foo[]` to be obsolete syntax. Modify the obsolete mechanism to support warnings. --- src/libsyntax/parse/obsolete.rs | 26 +++++++++++++++++++++----- src/libsyntax/parse/parser.rs | 9 ++++----- src/test/compile-fail/slice-1.rs | 8 +++----- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 1df2e762ee748..c6d852627c6ae 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -28,6 +28,7 @@ pub enum ObsoleteSyntax { ProcExpr, ClosureType, ClosureKind, + EmptyIndex, } pub trait ParserObsoleteMethods { @@ -48,35 +49,46 @@ pub trait ParserObsoleteMethods { impl<'a> ParserObsoleteMethods for parser::Parser<'a> { /// Reports an obsolete syntax non-fatal error. fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) { - let (kind_str, desc) = match kind { + let (kind_str, desc, error) = match kind { ObsoleteSyntax::ForSized => ( "for Sized?", "no longer required. Traits (and their `Self` type) do not have the `Sized` bound \ by default", + true, ), ObsoleteSyntax::ProcType => ( "the `proc` type", "use unboxed closures instead", + true, ), ObsoleteSyntax::ProcExpr => ( "`proc` expression", "use a `move ||` expression instead", + true, ), ObsoleteSyntax::ClosureType => ( "`|usize| -> bool` closure type", "use unboxed closures instead, no type annotation needed" + true, ), ObsoleteSyntax::ClosureKind => ( "`:`, `&mut:`, or `&:`", "rely on inference instead" + true, ), ObsoleteSyntax::Sized => ( "`Sized? T` for removing the `Sized` bound", "write `T: ?Sized` instead" + true, + ), + ObsoleteSyntax::EmptyIndex => ( + "[]", + "write `[..]` instead", + false, // warning for now ), }; - self.report(sp, kind, kind_str, desc); + self.report(sp, kind, kind_str, desc, error); } /// Reports an obsolete syntax non-fatal error, and returns @@ -90,9 +102,13 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> { sp: Span, kind: ObsoleteSyntax, kind_str: &str, - desc: &str) { - self.span_err(sp, - &format!("obsolete syntax: {}", kind_str)[]); + desc: &str, + error: bool) { + if error { + self.span_err(sp, &format!("obsolete syntax: {}", kind_str)[]); + } else { + self.span_warn(sp, &format!("obsolete syntax: {}", kind_str)[]); + } if !self.obsolete_set.contains(&kind) { self.sess diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 407740e580d2e..7d3a7d6010145 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2552,8 +2552,9 @@ impl<'a> Parser<'a> { parameters: ast::PathParameters::none(), } }).collect(); + let span = mk_sp(lo, hi); let path = ast::Path { - span: mk_sp(lo, hi), + span: span, global: true, segments: segments, }; @@ -2562,10 +2563,8 @@ impl<'a> Parser<'a> { let ix = self.mk_expr(bracket_pos, hi, range); let index = self.mk_index(e, ix); e = self.mk_expr(lo, hi, index); - // Enable after snapshot. - // self.span_warn(e.span, "deprecated slicing syntax: `[]`"); - // self.span_note(e.span, - // "use `&expr[..]` to construct a slice of the whole of expr"); + + self.obsolete(span, ObsoleteSyntax::EmptyIndex); } else { let ix = self.parse_expr(); hi = self.span.hi; diff --git a/src/test/compile-fail/slice-1.rs b/src/test/compile-fail/slice-1.rs index 23ad5b09950ef..3b992e3bcc321 100644 --- a/src/test/compile-fail/slice-1.rs +++ b/src/test/compile-fail/slice-1.rs @@ -9,14 +9,12 @@ // except according to those terms. // Test slicing &expr[] is deprecated and gives a helpful error message. -// -// ignore-test struct Foo; fn main() { let x = Foo; - &x[]; //~ WARNING deprecated slicing syntax: `[]` - //~^ NOTE use `&expr[..]` to construct a slice of the whole of expr - //~^^ ERROR cannot index a value of type `Foo` + &x[]; + //~^ WARN obsolete syntax + //~| ERROR cannot index } From 9ea84aeed4ed3006eddb6a7b24e9714f2844cd22 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 18 Feb 2015 14:48:57 -0500 Subject: [PATCH 67/76] Replace all uses of `&foo[]` with `&foo[..]` en masse. --- src/compiletest/runtest.rs | 2 +- src/doc/reference.md | 2 +- src/doc/trpl/patterns.md | 2 +- src/libcollections/slice.rs | 20 ++-- src/libcollections/str.rs | 94 +++++++++---------- src/libcollections/string.rs | 10 +- src/libcollections/vec.rs | 2 +- src/libcore/array.rs | 28 +++--- src/libcore/str/mod.rs | 2 +- src/libcoretest/iter.rs | 2 +- src/libcoretest/slice.rs | 12 +-- src/libfmt_macros/lib.rs | 4 +- src/libgetopts/lib.rs | 30 +++--- src/libgraphviz/lib.rs | 6 +- src/liblog/lib.rs | 6 +- src/librustc/lint/builtin.rs | 16 ++-- src/librustc/lint/context.rs | 34 +++---- src/librustc/metadata/creader.rs | 12 +-- src/librustc/metadata/encoder.rs | 10 +- src/librustc/metadata/loader.rs | 12 +-- src/librustc/metadata/tydecode.rs | 2 +- src/librustc/middle/astencode.rs | 2 +- src/librustc/middle/cfg/graphviz.rs | 2 +- src/librustc/middle/check_match.rs | 14 +-- src/librustc/middle/const_eval.rs | 10 +- src/librustc/middle/dataflow.rs | 4 +- src/librustc/middle/dead.rs | 2 +- src/librustc/middle/expr_use_visitor.rs | 2 +- src/librustc/middle/infer/combine.rs | 2 +- src/librustc/middle/infer/error_reporting.rs | 14 +-- .../middle/infer/region_inference/mod.rs | 2 +- src/librustc/middle/lang_items.rs | 2 +- src/librustc/middle/liveness.rs | 8 +- src/librustc/middle/traits/select.rs | 2 +- src/librustc/middle/ty.rs | 14 +-- src/librustc/middle/weak_lang_items.rs | 2 +- src/librustc/plugin/load.rs | 6 +- src/librustc/session/config.rs | 10 +- src/librustc/session/mod.rs | 4 +- src/librustc/util/lev_distance.rs | 2 +- src/librustc/util/ppaux.rs | 12 +-- src/librustc_back/archive.rs | 20 ++-- src/librustc_back/rpath.rs | 14 +-- src/librustc_back/target/mod.rs | 6 +- src/librustc_borrowck/borrowck/check_loans.rs | 2 +- src/librustc_borrowck/borrowck/fragments.rs | 28 +++--- src/librustc_borrowck/borrowck/mod.rs | 2 +- src/librustc_borrowck/graphviz.rs | 2 +- src/librustc_driver/driver.rs | 8 +- src/librustc_driver/lib.rs | 10 +- src/librustc_driver/pretty.rs | 12 +-- src/librustc_driver/test.rs | 2 +- src/librustc_privacy/lib.rs | 6 +- src/librustc_resolve/lib.rs | 54 +++++------ src/librustc_trans/back/link.rs | 46 ++++----- src/librustc_trans/back/lto.rs | 2 +- src/librustc_trans/back/write.rs | 24 ++--- src/librustc_trans/save/mod.rs | 88 ++++++++--------- src/librustc_trans/save/recorder.rs | 12 +-- src/librustc_trans/trans/_match.rs | 18 ++-- src/librustc_trans/trans/adt.rs | 42 ++++----- src/librustc_trans/trans/asm.rs | 12 +-- src/librustc_trans/trans/base.rs | 38 ++++---- src/librustc_trans/trans/builder.rs | 8 +- src/librustc_trans/trans/callee.rs | 8 +- src/librustc_trans/trans/cleanup.rs | 4 +- src/librustc_trans/trans/closure.rs | 4 +- src/librustc_trans/trans/common.rs | 4 +- src/librustc_trans/trans/consts.rs | 26 ++--- src/librustc_trans/trans/context.rs | 2 +- src/librustc_trans/trans/controlflow.rs | 6 +- src/librustc_trans/trans/debuginfo.rs | 74 +++++++-------- src/librustc_trans/trans/expr.rs | 18 ++-- src/librustc_trans/trans/foreign.rs | 8 +- src/librustc_trans/trans/glue.rs | 6 +- src/librustc_trans/trans/intrinsic.rs | 8 +- src/librustc_trans/trans/monomorphize.rs | 10 +- src/librustc_trans/trans/type_of.rs | 8 +- src/librustc_typeck/astconv.rs | 10 +- src/librustc_typeck/check/_match.rs | 2 +- src/librustc_typeck/check/callee.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 2 +- src/librustc_typeck/check/method/suggest.rs | 4 +- src/librustc_typeck/check/mod.rs | 32 +++---- src/librustc_typeck/check/regionck.rs | 4 +- src/librustc_typeck/collect.rs | 10 +- src/librustc_typeck/variance.rs | 2 +- src/librustdoc/html/highlight.rs | 2 +- src/libserialize/json.rs | 12 +-- src/libserialize/serialize.rs | 2 +- src/libstd/ffi/os_str.rs | 8 +- src/libstd/io/buffered.rs | 4 +- src/libstd/io/cursor.rs | 14 +-- src/libstd/old_io/buffered.rs | 6 +- src/libstd/old_path/mod.rs | 4 +- src/libstd/old_path/windows.rs | 36 +++---- src/libstd/panicking.rs | 2 +- src/libstd/path.rs | 4 +- src/libstd/sys/windows/mod.rs | 4 +- src/libstd/sys/windows/os.rs | 10 +- src/libstd/sys/windows/process2.rs | 2 +- src/libsyntax/ast.rs | 2 +- src/libsyntax/ast_map/mod.rs | 24 ++--- src/libsyntax/ast_util.rs | 6 +- src/libsyntax/attr.rs | 28 +++--- src/libsyntax/codemap.rs | 2 +- src/libsyntax/config.rs | 2 +- src/libsyntax/diagnostic.rs | 24 ++--- src/libsyntax/diagnostics/plugin.rs | 8 +- src/libsyntax/ext/concat.rs | 2 +- src/libsyntax/ext/concat_idents.rs | 2 +- src/libsyntax/ext/deriving/bounds.rs | 2 +- src/libsyntax/ext/deriving/generic/mod.rs | 32 +++---- src/libsyntax/ext/deriving/mod.rs | 2 +- src/libsyntax/ext/deriving/show.rs | 2 +- src/libsyntax/ext/env.rs | 6 +- src/libsyntax/ext/expand.rs | 26 ++--- src/libsyntax/ext/format.rs | 8 +- src/libsyntax/ext/quote.rs | 4 +- src/libsyntax/ext/source_util.rs | 6 +- src/libsyntax/ext/tt/macro_parser.rs | 12 +-- src/libsyntax/ext/tt/macro_rules.rs | 6 +- src/libsyntax/ext/tt/transcribe.rs | 2 +- src/libsyntax/feature_gate.rs | 22 ++--- src/libsyntax/parse/lexer/comments.rs | 6 +- src/libsyntax/parse/lexer/mod.rs | 8 +- src/libsyntax/parse/mod.rs | 24 ++--- src/libsyntax/parse/obsolete.rs | 9 +- src/libsyntax/parse/parser.rs | 80 ++++++++-------- src/libsyntax/parse/token.rs | 4 +- src/libsyntax/print/pp.rs | 2 +- src/libsyntax/print/pprust.rs | 64 ++++++------- src/libsyntax/std_inject.rs | 2 +- src/libsyntax/test.rs | 12 +-- src/libsyntax/util/interner.rs | 10 +- src/libterm/terminfo/mod.rs | 2 +- src/libterm/terminfo/searcher.rs | 4 +- src/libtest/lib.rs | 4 +- src/rustbook/build.rs | 2 +- src/rustbook/error.rs | 4 +- src/rustbook/test.rs | 2 +- src/test/auxiliary/lint_group_plugin_test.rs | 4 +- src/test/auxiliary/lint_plugin_test.rs | 2 +- src/test/auxiliary/plugin_args.rs | 2 +- src/test/run-pass/regions-refcell.rs | 8 +- 145 files changed, 865 insertions(+), 864 deletions(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 658c0cb3f4e83..047a9e38d520f 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -688,7 +688,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) .unwrap() .to_string(); - script_str.push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[])[]); + script_str.push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[..])[]); script_str.push_str("type summary add --no-value "); script_str.push_str("--python-function lldb_rust_formatters.print_val "); script_str.push_str("-x \".*\" --category Rust\n"); diff --git a/src/doc/reference.md b/src/doc/reference.md index 00ed5d4562b11..ad8377a59e41c 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -3587,7 +3587,7 @@ An example of each kind: ```{rust} let vec: Vec = vec![1, 2, 3]; let arr: [i32; 3] = [1, 2, 3]; -let s: &[i32] = &vec[]; +let s: &[i32] = &vec[..]; ``` As you can see, the `vec!` macro allows you to create a `Vec` easily. The diff --git a/src/doc/trpl/patterns.md b/src/doc/trpl/patterns.md index 122cffe36975f..9e82e48fd18b7 100644 --- a/src/doc/trpl/patterns.md +++ b/src/doc/trpl/patterns.md @@ -180,7 +180,7 @@ If you want to match against a slice or array, you can use `&`: fn main() { let v = vec!["match_this", "1"]; - match &v[] { + match &v[..] { ["match_this", second] => println!("The second element is {}", second), _ => {}, } diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 06ae8127c00fb..2147b6471464b 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1177,12 +1177,12 @@ impl ElementSwaps { #[unstable(feature = "collections", reason = "trait is unstable")] impl BorrowFrom> for [T] { - fn borrow_from(owned: &Vec) -> &[T] { &owned[] } + fn borrow_from(owned: &Vec) -> &[T] { &owned[..] } } #[unstable(feature = "collections", reason = "trait is unstable")] impl BorrowFromMut> for [T] { - fn borrow_from_mut(owned: &mut Vec) -> &mut [T] { &mut owned[] } + fn borrow_from_mut(owned: &mut Vec) -> &mut [T] { &mut owned[..] } } #[unstable(feature = "collections", reason = "trait is unstable")] @@ -1743,7 +1743,7 @@ mod tests { #[test] fn test_slice_from() { let vec: &[_] = &[1, 2, 3, 4]; - assert_eq!(&vec[], vec); + assert_eq!(&vec[..], vec); let b: &[_] = &[3, 4]; assert_eq!(&vec[2..], b); let b: &[_] = &[]; @@ -1996,9 +1996,9 @@ mod tests { #[test] fn test_lexicographic_permutations_empty_and_short() { - let empty : &mut[i32] = &mut[]; + let empty : &mut[i32] = &mut[..]; assert!(empty.next_permutation() == false); - let b: &mut[i32] = &mut[]; + let b: &mut[i32] = &mut[..]; assert!(empty == b); assert!(empty.prev_permutation() == false); assert!(empty == b); @@ -2264,15 +2264,15 @@ mod tests { #[test] fn test_total_ord() { let c = &[1, 2, 3]; - [1, 2, 3, 4][].cmp(c) == Greater; + [1, 2, 3, 4][..].cmp(c) == Greater; let c = &[1, 2, 3, 4]; - [1, 2, 3][].cmp(c) == Less; + [1, 2, 3][..].cmp(c) == Less; let c = &[1, 2, 3, 6]; - [1, 2, 3, 4][].cmp(c) == Equal; + [1, 2, 3, 4][..].cmp(c) == Equal; let c = &[1, 2, 3, 4, 5, 6]; - [1, 2, 3, 4, 5, 5, 5, 5][].cmp(c) == Less; + [1, 2, 3, 4, 5, 5, 5, 5][..].cmp(c) == Less; let c = &[1, 2, 3, 4]; - [2, 2][].cmp(c) == Greater; + [2, 2][..].cmp(c) == Greater; } #[test] diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 2d4dc2bcf30d3..6ba5db0fb9df5 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -388,7 +388,7 @@ macro_rules! utf8_acc_cont_byte { #[unstable(feature = "collections", reason = "trait is unstable")] impl BorrowFrom for str { - fn borrow_from(owned: &String) -> &str { &owned[] } + fn borrow_from(owned: &String) -> &str { &owned[..] } } #[unstable(feature = "collections", reason = "trait is unstable")] @@ -466,7 +466,7 @@ pub trait StrExt: Index { reason = "this functionality may be moved to libunicode")] fn nfd_chars(&self) -> Decompositions { Decompositions { - iter: self[].chars(), + iter: self[..].chars(), buffer: Vec::new(), sorted: false, kind: Canonical @@ -480,7 +480,7 @@ pub trait StrExt: Index { reason = "this functionality may be moved to libunicode")] fn nfkd_chars(&self) -> Decompositions { Decompositions { - iter: self[].chars(), + iter: self[..].chars(), buffer: Vec::new(), sorted: false, kind: Compatible @@ -530,7 +530,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn contains(&self, pat: &str) -> bool { - core_str::StrExt::contains(&self[], pat) + core_str::StrExt::contains(&self[..], pat) } /// Returns true if a string contains a char pattern. @@ -547,7 +547,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "might get removed in favour of a more generic contains()")] fn contains_char(&self, pat: P) -> bool { - core_str::StrExt::contains_char(&self[], pat) + core_str::StrExt::contains_char(&self[..], pat) } /// An iterator over the characters of `self`. Note, this iterates @@ -561,7 +561,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn chars(&self) -> Chars { - core_str::StrExt::chars(&self[]) + core_str::StrExt::chars(&self[..]) } /// An iterator over the bytes of `self` @@ -574,13 +574,13 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn bytes(&self) -> Bytes { - core_str::StrExt::bytes(&self[]) + core_str::StrExt::bytes(&self[..]) } /// An iterator over the characters of `self` and their byte offsets. #[stable(feature = "rust1", since = "1.0.0")] fn char_indices(&self) -> CharIndices { - core_str::StrExt::char_indices(&self[]) + core_str::StrExt::char_indices(&self[..]) } /// An iterator over substrings of `self`, separated by characters @@ -603,7 +603,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn split(&self, pat: P) -> Split

{ - core_str::StrExt::split(&self[], pat) + core_str::StrExt::split(&self[..], pat) } /// An iterator over substrings of `self`, separated by characters @@ -630,7 +630,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn splitn(&self, count: usize, pat: P) -> SplitN

{ - core_str::StrExt::splitn(&self[], count, pat) + core_str::StrExt::splitn(&self[..], count, pat) } /// An iterator over substrings of `self`, separated by characters @@ -659,7 +659,7 @@ pub trait StrExt: Index { /// ``` #[unstable(feature = "collections", reason = "might get removed")] fn split_terminator(&self, pat: P) -> SplitTerminator

{ - core_str::StrExt::split_terminator(&self[], pat) + core_str::StrExt::split_terminator(&self[..], pat) } /// An iterator over substrings of `self`, separated by characters @@ -680,7 +680,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn rsplitn(&self, count: usize, pat: P) -> RSplitN

{ - core_str::StrExt::rsplitn(&self[], count, pat) + core_str::StrExt::rsplitn(&self[..], count, pat) } /// An iterator over the start and end indices of the disjoint @@ -706,7 +706,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "might have its iterator type changed")] fn match_indices<'a>(&'a self, pat: &'a str) -> MatchIndices<'a> { - core_str::StrExt::match_indices(&self[], pat) + core_str::StrExt::match_indices(&self[..], pat) } /// An iterator over the substrings of `self` separated by the pattern `sep`. @@ -723,7 +723,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "might get removed in the future in favor of a more generic split()")] fn split_str<'a>(&'a self, pat: &'a str) -> SplitStr<'a> { - core_str::StrExt::split_str(&self[], pat) + core_str::StrExt::split_str(&self[..], pat) } /// An iterator over the lines of a string (subsequences separated @@ -739,7 +739,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn lines(&self) -> Lines { - core_str::StrExt::lines(&self[]) + core_str::StrExt::lines(&self[..]) } /// An iterator over the lines of a string, separated by either @@ -755,7 +755,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn lines_any(&self) -> LinesAny { - core_str::StrExt::lines_any(&self[]) + core_str::StrExt::lines_any(&self[..]) } /// Deprecated: use `s[a .. b]` instead. @@ -802,7 +802,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "may have yet to prove its worth")] fn slice_chars(&self, begin: usize, end: usize) -> &str { - core_str::StrExt::slice_chars(&self[], begin, end) + core_str::StrExt::slice_chars(&self[..], begin, end) } /// Takes a bytewise (not UTF-8) slice from a string. @@ -813,7 +813,7 @@ pub trait StrExt: Index { /// the entire slice as well. #[stable(feature = "rust1", since = "1.0.0")] unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str { - core_str::StrExt::slice_unchecked(&self[], begin, end) + core_str::StrExt::slice_unchecked(&self[..], begin, end) } /// Returns true if the pattern `pat` is a prefix of the string. @@ -825,7 +825,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn starts_with(&self, pat: &str) -> bool { - core_str::StrExt::starts_with(&self[], pat) + core_str::StrExt::starts_with(&self[..], pat) } /// Returns true if the pattern `pat` is a suffix of the string. @@ -837,7 +837,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn ends_with(&self, pat: &str) -> bool { - core_str::StrExt::ends_with(&self[], pat) + core_str::StrExt::ends_with(&self[..], pat) } /// Returns a string with all pre- and suffixes that match @@ -857,7 +857,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn trim_matches(&self, pat: P) -> &str { - core_str::StrExt::trim_matches(&self[], pat) + core_str::StrExt::trim_matches(&self[..], pat) } /// Returns a string with all prefixes that match @@ -877,7 +877,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn trim_left_matches(&self, pat: P) -> &str { - core_str::StrExt::trim_left_matches(&self[], pat) + core_str::StrExt::trim_left_matches(&self[..], pat) } /// Returns a string with all suffixes that match @@ -897,7 +897,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn trim_right_matches(&self, pat: P) -> &str { - core_str::StrExt::trim_right_matches(&self[], pat) + core_str::StrExt::trim_right_matches(&self[..], pat) } /// Check that `index`-th byte lies at the start and/or end of a @@ -926,7 +926,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "naming is uncertain with container conventions")] fn is_char_boundary(&self, index: usize) -> bool { - core_str::StrExt::is_char_boundary(&self[], index) + core_str::StrExt::is_char_boundary(&self[..], index) } /// Pluck a character out of a string and return the index of the next @@ -985,7 +985,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "naming is uncertain with container conventions")] fn char_range_at(&self, start: usize) -> CharRange { - core_str::StrExt::char_range_at(&self[], start) + core_str::StrExt::char_range_at(&self[..], start) } /// Given a byte position and a str, return the previous char and its position. @@ -1001,7 +1001,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "naming is uncertain with container conventions")] fn char_range_at_reverse(&self, start: usize) -> CharRange { - core_str::StrExt::char_range_at_reverse(&self[], start) + core_str::StrExt::char_range_at_reverse(&self[..], start) } /// Plucks the character starting at the `i`th byte of a string. @@ -1022,7 +1022,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "naming is uncertain with container conventions")] fn char_at(&self, i: usize) -> char { - core_str::StrExt::char_at(&self[], i) + core_str::StrExt::char_at(&self[..], i) } /// Plucks the character ending at the `i`th byte of a string. @@ -1034,7 +1034,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "naming is uncertain with container conventions")] fn char_at_reverse(&self, i: usize) -> char { - core_str::StrExt::char_at_reverse(&self[], i) + core_str::StrExt::char_at_reverse(&self[..], i) } /// Work with the byte buffer of a string as a byte slice. @@ -1046,7 +1046,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn as_bytes(&self) -> &[u8] { - core_str::StrExt::as_bytes(&self[]) + core_str::StrExt::as_bytes(&self[..]) } /// Returns the byte index of the first character of `self` that @@ -1074,7 +1074,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn find(&self, pat: P) -> Option { - core_str::StrExt::find(&self[], pat) + core_str::StrExt::find(&self[..], pat) } /// Returns the byte index of the last character of `self` that @@ -1102,7 +1102,7 @@ pub trait StrExt: Index { /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn rfind(&self, pat: P) -> Option { - core_str::StrExt::rfind(&self[], pat) + core_str::StrExt::rfind(&self[..], pat) } /// Returns the byte index of the first matching substring @@ -1127,7 +1127,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "might get removed in favor of a more generic find in the future")] fn find_str(&self, needle: &str) -> Option { - core_str::StrExt::find_str(&self[], needle) + core_str::StrExt::find_str(&self[..], needle) } /// Retrieves the first character from a string slice and returns @@ -1151,7 +1151,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "awaiting conventions about shifting and slices")] fn slice_shift_char(&self) -> Option<(char, &str)> { - core_str::StrExt::slice_shift_char(&self[]) + core_str::StrExt::slice_shift_char(&self[..]) } /// Returns the byte offset of an inner slice relative to an enclosing outer slice. @@ -1171,7 +1171,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "awaiting convention about comparability of arbitrary slices")] fn subslice_offset(&self, inner: &str) -> usize { - core_str::StrExt::subslice_offset(&self[], inner) + core_str::StrExt::subslice_offset(&self[..], inner) } /// Return an unsafe pointer to the strings buffer. @@ -1182,14 +1182,14 @@ pub trait StrExt: Index { #[stable(feature = "rust1", since = "1.0.0")] #[inline] fn as_ptr(&self) -> *const u8 { - core_str::StrExt::as_ptr(&self[]) + core_str::StrExt::as_ptr(&self[..]) } /// Return an iterator of `u16` over the string encoded as UTF-16. #[unstable(feature = "collections", reason = "this functionality may only be provided by libunicode")] fn utf16_units(&self) -> Utf16Units { - Utf16Units { encoder: Utf16Encoder::new(self[].chars()) } + Utf16Units { encoder: Utf16Encoder::new(self[..].chars()) } } /// Return the number of bytes in this string @@ -1203,7 +1203,7 @@ pub trait StrExt: Index { #[stable(feature = "rust1", since = "1.0.0")] #[inline] fn len(&self) -> usize { - core_str::StrExt::len(&self[]) + core_str::StrExt::len(&self[..]) } /// Returns true if this slice contains no bytes @@ -1216,7 +1216,7 @@ pub trait StrExt: Index { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn is_empty(&self) -> bool { - core_str::StrExt::is_empty(&self[]) + core_str::StrExt::is_empty(&self[..]) } /// Parse this string into the specified type. @@ -1230,7 +1230,7 @@ pub trait StrExt: Index { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn parse(&self) -> Result { - core_str::StrExt::parse(&self[]) + core_str::StrExt::parse(&self[..]) } /// Returns an iterator over the @@ -1255,7 +1255,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "this functionality may only be provided by libunicode")] fn graphemes(&self, is_extended: bool) -> Graphemes { - UnicodeStr::graphemes(&self[], is_extended) + UnicodeStr::graphemes(&self[..], is_extended) } /// Returns an iterator over the grapheme clusters of self and their byte offsets. @@ -1271,7 +1271,7 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "this functionality may only be provided by libunicode")] fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices { - UnicodeStr::grapheme_indices(&self[], is_extended) + UnicodeStr::grapheme_indices(&self[..], is_extended) } /// An iterator over the words of a string (subsequences separated @@ -1288,7 +1288,7 @@ pub trait StrExt: Index { #[unstable(feature = "str_words", reason = "the precise algorithm to use is unclear")] fn words(&self) -> Words { - UnicodeStr::words(&self[]) + UnicodeStr::words(&self[..]) } /// Returns a string's displayed width in columns, treating control @@ -1303,25 +1303,25 @@ pub trait StrExt: Index { #[unstable(feature = "collections", reason = "this functionality may only be provided by libunicode")] fn width(&self, is_cjk: bool) -> usize { - UnicodeStr::width(&self[], is_cjk) + UnicodeStr::width(&self[..], is_cjk) } /// Returns a string with leading and trailing whitespace removed. #[stable(feature = "rust1", since = "1.0.0")] fn trim(&self) -> &str { - UnicodeStr::trim(&self[]) + UnicodeStr::trim(&self[..]) } /// Returns a string with leading whitespace removed. #[stable(feature = "rust1", since = "1.0.0")] fn trim_left(&self) -> &str { - UnicodeStr::trim_left(&self[]) + UnicodeStr::trim_left(&self[..]) } /// Returns a string with trailing whitespace removed. #[stable(feature = "rust1", since = "1.0.0")] fn trim_right(&self) -> &str { - UnicodeStr::trim_right(&self[]) + UnicodeStr::trim_right(&self[..]) } } @@ -2704,7 +2704,7 @@ mod tests { &["\u{378}\u{308}\u{903}"], &["\u{378}\u{308}", "\u{903}"]), ]; - for &(s, g) in &test_same[] { + for &(s, g) in &test_same[..] { // test forward iterator assert!(order::equals(s.graphemes(true), g.iter().cloned())); assert!(order::equals(s.graphemes(false), g.iter().cloned())); diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 69fd28d172368..cb3dca311224b 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -857,7 +857,7 @@ impl ops::Index> for String { type Output = str; #[inline] fn index(&self, index: &ops::Range) -> &str { - &self[][*index] + &self[..][*index] } } #[stable(feature = "rust1", since = "1.0.0")] @@ -865,7 +865,7 @@ impl ops::Index> for String { type Output = str; #[inline] fn index(&self, index: &ops::RangeTo) -> &str { - &self[][*index] + &self[..][*index] } } #[stable(feature = "rust1", since = "1.0.0")] @@ -873,7 +873,7 @@ impl ops::Index> for String { type Output = str; #[inline] fn index(&self, index: &ops::RangeFrom) -> &str { - &self[][*index] + &self[..][*index] } } #[stable(feature = "rust1", since = "1.0.0")] @@ -891,7 +891,7 @@ impl ops::Deref for String { #[inline] fn deref(&self) -> &str { - unsafe { mem::transmute(&self.vec[]) } + unsafe { mem::transmute(&self.vec[..]) } } } @@ -1287,7 +1287,7 @@ mod tests { #[test] fn test_slicing() { let s = "foobar".to_string(); - assert_eq!("foobar", &s[]); + assert_eq!("foobar", &s[..]); assert_eq!("foo", &s[..3]); assert_eq!("bar", &s[3..]); assert_eq!("oob", &s[1..4]); diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index bde733644b5b5..e593e45172c60 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -2589,7 +2589,7 @@ mod tests { b.bytes = src_len as u64; b.iter(|| { - let dst = src.clone()[].to_vec(); + let dst = src.clone()[..].to_vec(); assert_eq!(dst.len(), src_len); assert!(dst.iter().enumerate().all(|(i, x)| i == *x)); }); diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 838ca4e478b72..45c0f65197aa4 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -37,14 +37,14 @@ macro_rules! array_impls { impl> Hash for [T; $N] { fn hash(&self, state: &mut S) { - Hash::hash(&self[], state) + Hash::hash(&self[..], state) } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for [T; $N] { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&&self[], f) + fmt::Debug::fmt(&&self[..], f) } } @@ -72,11 +72,11 @@ macro_rules! array_impls { impl PartialEq<[B; $N]> for [A; $N] where A: PartialEq { #[inline] fn eq(&self, other: &[B; $N]) -> bool { - &self[] == &other[] + &self[..] == &other[..] } #[inline] fn ne(&self, other: &[B; $N]) -> bool { - &self[] != &other[] + &self[..] != &other[..] } } @@ -87,11 +87,11 @@ macro_rules! array_impls { { #[inline(always)] fn eq(&self, other: &Rhs) -> bool { - PartialEq::eq(&self[], &**other) + PartialEq::eq(&self[..], &**other) } #[inline(always)] fn ne(&self, other: &Rhs) -> bool { - PartialEq::ne(&self[], &**other) + PartialEq::ne(&self[..], &**other) } } @@ -102,11 +102,11 @@ macro_rules! array_impls { { #[inline(always)] fn eq(&self, other: &[B; $N]) -> bool { - PartialEq::eq(&**self, &other[]) + PartialEq::eq(&**self, &other[..]) } #[inline(always)] fn ne(&self, other: &[B; $N]) -> bool { - PartialEq::ne(&**self, &other[]) + PartialEq::ne(&**self, &other[..]) } } @@ -117,23 +117,23 @@ macro_rules! array_impls { impl PartialOrd for [T; $N] { #[inline] fn partial_cmp(&self, other: &[T; $N]) -> Option { - PartialOrd::partial_cmp(&&self[], &&other[]) + PartialOrd::partial_cmp(&&self[..], &&other[..]) } #[inline] fn lt(&self, other: &[T; $N]) -> bool { - PartialOrd::lt(&&self[], &&other[]) + PartialOrd::lt(&&self[..], &&other[..]) } #[inline] fn le(&self, other: &[T; $N]) -> bool { - PartialOrd::le(&&self[], &&other[]) + PartialOrd::le(&&self[..], &&other[..]) } #[inline] fn ge(&self, other: &[T; $N]) -> bool { - PartialOrd::ge(&&self[], &&other[]) + PartialOrd::ge(&&self[..], &&other[..]) } #[inline] fn gt(&self, other: &[T; $N]) -> bool { - PartialOrd::gt(&&self[], &&other[]) + PartialOrd::gt(&&self[..], &&other[..]) } } @@ -141,7 +141,7 @@ macro_rules! array_impls { impl Ord for [T; $N] { #[inline] fn cmp(&self, other: &[T; $N]) -> Ordering { - Ord::cmp(&&self[], &&other[]) + Ord::cmp(&&self[..], &&other[..]) } } )+ diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index ce26abe606dd4..eec997b9f10fc 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1280,7 +1280,7 @@ mod traits { /// Any string that can be represented as a slice #[unstable(feature = "core", reason = "Instead of taking this bound generically, this trait will be \ - replaced with one of slicing syntax (&foo[]), deref coercions, or \ + replaced with one of slicing syntax (&foo[..]), deref coercions, or \ a more generic conversion trait")] pub trait Str { /// Work with `self` as a slice. diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 7eb0fb97bed2a..4653a30a45d31 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -264,7 +264,7 @@ fn test_inspect() { .collect::>(); assert_eq!(n, xs.len()); - assert_eq!(&xs[], &ys[]); + assert_eq!(&xs[..], &ys[..]); } #[test] diff --git a/src/libcoretest/slice.rs b/src/libcoretest/slice.rs index 6d5cc38ef0a74..46c7730cc6470 100644 --- a/src/libcoretest/slice.rs +++ b/src/libcoretest/slice.rs @@ -43,13 +43,13 @@ fn iterator_to_slice() { { let mut iter = data.iter(); - assert_eq!(&iter[], &other_data[]); + assert_eq!(&iter[..], &other_data[..]); iter.next(); - assert_eq!(&iter[], &other_data[1..]); + assert_eq!(&iter[..], &other_data[1..]); iter.next_back(); - assert_eq!(&iter[], &other_data[1..2]); + assert_eq!(&iter[..], &other_data[1..2]); let s = iter.as_slice(); iter.next(); @@ -57,17 +57,17 @@ fn iterator_to_slice() { } { let mut iter = data.iter_mut(); - assert_eq!(&iter[], &other_data[]); + assert_eq!(&iter[..], &other_data[..]); // mutability: assert!(&mut iter[] == other_data); iter.next(); - assert_eq!(&iter[], &other_data[1..]); + assert_eq!(&iter[..], &other_data[1..]); assert!(&mut iter[] == &mut other_data[1..]); iter.next_back(); - assert_eq!(&iter[], &other_data[1..2]); + assert_eq!(&iter[..], &other_data[1..2]); assert!(&mut iter[] == &mut other_data[1..2]); let s = iter.into_slice(); diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 1c7e97d784c68..be77622ac1db7 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -215,11 +215,11 @@ impl<'a> Parser<'a> { } Some((_, other)) => { self.err(&format!("expected `{:?}`, found `{:?}`", c, - other)[]); + other)); } None => { self.err(&format!("expected `{:?}` but string was terminated", - c)[]); + c)); } } } diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index c743119f40909..fdd7f7395c2b7 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -287,7 +287,7 @@ impl OptGroup { impl Matches { fn opt_vals(&self, nm: &str) -> Vec { - match find_opt(&self.opts[], Name::from_str(nm)) { + match find_opt(&self.opts[..], Name::from_str(nm)) { Some(id) => self.vals[id].clone(), None => panic!("No option '{}' defined", nm) } @@ -326,7 +326,7 @@ impl Matches { /// Returns the string argument supplied to one of several matching options or `None`. pub fn opts_str(&self, names: &[String]) -> Option { for nm in names { - match self.opt_val(&nm[]) { + match self.opt_val(&nm[..]) { Some(Val(ref s)) => return Some(s.clone()), _ => () } @@ -593,7 +593,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result { while i < l { let cur = args[i].clone(); let curlen = cur.len(); - if !is_arg(&cur[]) { + if !is_arg(&cur[..]) { free.push(cur); } else if cur == "--" { let mut j = i + 1; @@ -667,7 +667,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result { v.push(Val((i_arg.clone()) .unwrap())); } else if name_pos < names.len() || i + 1 == l || - is_arg(&args[i + 1][]) { + is_arg(&args[i + 1][..]) { let v = &mut vals[optid]; v.push(Given); } else { @@ -730,7 +730,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String { 0 => {} 1 => { row.push('-'); - row.push_str(&short_name[]); + row.push_str(&short_name[..]); row.push(' '); } _ => panic!("the short name should only be 1 ascii char long"), @@ -741,7 +741,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String { 0 => {} _ => { row.push_str("--"); - row.push_str(&long_name[]); + row.push_str(&long_name[..]); row.push(' '); } } @@ -749,10 +749,10 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String { // arg match hasarg { No => {} - Yes => row.push_str(&hint[]), + Yes => row.push_str(&hint[..]), Maybe => { row.push('['); - row.push_str(&hint[]); + row.push_str(&hint[..]); row.push(']'); } } @@ -765,7 +765,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String { row.push(' '); } } else { - row.push_str(&desc_sep[]); + row.push_str(&desc_sep[..]); } // Normalize desc to contain words separated by one space character @@ -777,14 +777,14 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String { // FIXME: #5516 should be graphemes not codepoints let mut desc_rows = Vec::new(); - each_split_within(&desc_normalized_whitespace[], 54, |substr| { + each_split_within(&desc_normalized_whitespace[..], 54, |substr| { desc_rows.push(substr.to_string()); true }); // FIXME: #5516 should be graphemes not codepoints // wrapped description - row.push_str(&desc_rows.connect(&desc_sep[])[]); + row.push_str(&desc_rows.connect(&desc_sep[..])[]); row }); @@ -803,10 +803,10 @@ fn format_option(opt: &OptGroup) -> String { // Use short_name is possible, but fallback to long_name. if opt.short_name.len() > 0 { line.push('-'); - line.push_str(&opt.short_name[]); + line.push_str(&opt.short_name[..]); } else { line.push_str("--"); - line.push_str(&opt.long_name[]); + line.push_str(&opt.long_name[..]); } if opt.hasarg != No { @@ -814,7 +814,7 @@ fn format_option(opt: &OptGroup) -> String { if opt.hasarg == Maybe { line.push('['); } - line.push_str(&opt.hint[]); + line.push_str(&opt.hint[..]); if opt.hasarg == Maybe { line.push(']'); } @@ -836,7 +836,7 @@ pub fn short_usage(program_name: &str, opts: &[OptGroup]) -> String { line.push_str(&opts.iter() .map(format_option) .collect::>() - .connect(" ")[]); + .connect(" ")[..]); line } diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 230deabee0034..02914afed2662 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -455,7 +455,7 @@ impl<'a> LabelText<'a> { pub fn escape(&self) -> String { match self { &LabelStr(ref s) => s.escape_default(), - &EscStr(ref s) => LabelText::escape_str(&s[]), + &EscStr(ref s) => LabelText::escape_str(&s[..]), } } @@ -484,7 +484,7 @@ impl<'a> LabelText<'a> { let mut prefix = self.pre_escaped_content().into_owned(); let suffix = suffix.pre_escaped_content(); prefix.push_str(r"\n\n"); - prefix.push_str(&suffix[]); + prefix.push_str(&suffix[..]); EscStr(prefix.into_cow()) } } @@ -678,7 +678,7 @@ mod tests { impl<'a> Labeller<'a, Node, &'a Edge> for LabelledGraph { fn graph_id(&'a self) -> Id<'a> { - Id::new(&self.name[]).unwrap() + Id::new(&self.name[..]).unwrap() } fn node_id(&'a self, n: &Node) -> Id<'a> { id_name(n) diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 4dab07acfd2a0..c2c7f20ce9cdf 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -287,7 +287,7 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) { // Test the literal string from args against the current filter, if there // is one. match unsafe { FILTER.as_ref() } { - Some(filter) if !args.to_string().contains(&filter[]) => return, + Some(filter) if !args.to_string().contains(&filter[..]) => return, _ => {} } @@ -382,7 +382,7 @@ fn enabled(level: u32, // Search for the longest match, the vector is assumed to be pre-sorted. for directive in iter.rev() { match directive.name { - Some(ref name) if !module.starts_with(&name[]) => {}, + Some(ref name) if !module.starts_with(&name[..]) => {}, Some(..) | None => { return level <= directive.level } @@ -397,7 +397,7 @@ fn enabled(level: u32, /// `Once` primitive (and this function is called from that primitive). fn init() { let (mut directives, filter) = match env::var("RUST_LOG") { - Ok(spec) => directive::parse_logging_spec(&spec[]), + Ok(spec) => directive::parse_logging_spec(&spec[..]), Err(..) => (Vec::new(), None), }; diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index ba108b5488ede..6a329b7c72b20 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -509,7 +509,7 @@ impl BoxPointers { if n_uniq > 0 { let s = ty_to_string(cx.tcx, ty); let m = format!("type uses owned (Box type) pointers: {}", s); - cx.span_lint(BOX_POINTERS, span, &m[]); + cx.span_lint(BOX_POINTERS, span, &m[..]); } } } @@ -737,7 +737,7 @@ impl LintPass for UnusedResults { } } else { let attrs = csearch::get_item_attrs(&cx.sess().cstore, did); - warned |= check_must_use(cx, &attrs[], s.span); + warned |= check_must_use(cx, &attrs[..], s.span); } } _ => {} @@ -804,7 +804,7 @@ impl NonCamelCaseTypes { } else { format!("{} `{}` should have a camel case name such as `{}`", sort, s, c) }; - cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m[]); + cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m[..]); } } } @@ -951,7 +951,7 @@ impl NonSnakeCase { if !is_snake_case(ident) { let sc = NonSnakeCase::to_snake_case(&s); - if sc != &s[] { + if sc != &s[..] { cx.span_lint(NON_SNAKE_CASE, span, &*format!("{} `{}` should have a snake case name such as `{}`", sort, s, sc)); @@ -1034,7 +1034,7 @@ impl NonUpperCaseGlobals { if s.chars().any(|c| c.is_lowercase()) { let uc: String = NonSnakeCase::to_snake_case(&s).chars() .map(|c| c.to_uppercase()).collect(); - if uc != &s[] { + if uc != &s[..] { cx.span_lint(NON_UPPER_CASE_GLOBALS, span, &format!("{} `{}` should have an upper case name such as `{}`", sort, s, uc)); @@ -1197,7 +1197,7 @@ impl LintPass for UnusedImportBraces { let m = format!("braces around {} is unnecessary", &token::get_ident(*name)); cx.span_lint(UNUSED_IMPORT_BRACES, item.span, - &m[]); + &m[..]); }, _ => () } @@ -1475,7 +1475,7 @@ impl LintPass for MissingDoc { let doc_hidden = self.doc_hidden() || attrs.iter().any(|attr| { attr.check_name("doc") && match attr.meta_item_list() { None => false, - Some(l) => attr::contains_name(&l[], "hidden"), + Some(l) => attr::contains_name(&l[..], "hidden"), } }); self.doc_hidden_stack.push(doc_hidden); @@ -1703,7 +1703,7 @@ impl Stability { _ => format!("use of {} item", label) }; - cx.span_lint(lint, span, &msg[]); + cx.span_lint(lint, span, &msg[..]); } } } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 42a6861f452a6..068c179d3431f 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -125,11 +125,11 @@ impl LintStore { match (sess, from_plugin) { // We load builtin lints first, so a duplicate is a compiler bug. // Use early_error when handling -W help with no crate. - (None, _) => early_error(&msg[]), - (Some(sess), false) => sess.bug(&msg[]), + (None, _) => early_error(&msg[..]), + (Some(sess), false) => sess.bug(&msg[..]), // A duplicate name from a plugin is a user error. - (Some(sess), true) => sess.err(&msg[]), + (Some(sess), true) => sess.err(&msg[..]), } } @@ -150,11 +150,11 @@ impl LintStore { match (sess, from_plugin) { // We load builtin lints first, so a duplicate is a compiler bug. // Use early_error when handling -W help with no crate. - (None, _) => early_error(&msg[]), - (Some(sess), false) => sess.bug(&msg[]), + (None, _) => early_error(&msg[..]), + (Some(sess), false) => sess.bug(&msg[..]), // A duplicate name from a plugin is a user error. - (Some(sess), true) => sess.err(&msg[]), + (Some(sess), true) => sess.err(&msg[..]), } } } @@ -251,8 +251,8 @@ impl LintStore { let warning = format!("lint {} has been renamed to {}", lint_name, new_name); match span { - Some(span) => sess.span_warn(span, &warning[]), - None => sess.warn(&warning[]), + Some(span) => sess.span_warn(span, &warning[..]), + None => sess.warn(&warning[..]), }; Some(lint_id) } @@ -262,13 +262,13 @@ impl LintStore { pub fn process_command_line(&mut self, sess: &Session) { for &(ref lint_name, level) in &sess.opts.lint_opts { - match self.find_lint(&lint_name[], sess, None) { + match self.find_lint(&lint_name[..], sess, None) { Some(lint_id) => self.set_level(lint_id, (level, CommandLine)), None => { match self.lint_groups.iter().map(|(&x, pair)| (x, pair.0.clone())) .collect::>>() - .get(&lint_name[]) { + .get(&lint_name[..]) { Some(v) => { v.iter() .map(|lint_id: &LintId| @@ -411,15 +411,15 @@ pub fn raw_emit_lint(sess: &Session, lint: &'static Lint, if level == Forbid { level = Deny; } match (level, span) { - (Warn, Some(sp)) => sess.span_warn(sp, &msg[]), - (Warn, None) => sess.warn(&msg[]), - (Deny, Some(sp)) => sess.span_err(sp, &msg[]), - (Deny, None) => sess.err(&msg[]), + (Warn, Some(sp)) => sess.span_warn(sp, &msg[..]), + (Warn, None) => sess.warn(&msg[..]), + (Deny, Some(sp)) => sess.span_err(sp, &msg[..]), + (Deny, None) => sess.err(&msg[..]), _ => sess.bug("impossible level in raw_emit_lint"), } if let Some(note) = note { - sess.note(¬e[]); + sess.note(¬e[..]); } if let Some(span) = def { @@ -503,7 +503,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { match self.lints.find_lint(&lint_name, &self.tcx.sess, Some(span)) { Some(lint_id) => vec![(lint_id, level, span)], None => { - match self.lints.lint_groups.get(&lint_name[]) { + match self.lints.lint_groups.get(&lint_name[..]) { Some(&(ref v, _)) => v.iter() .map(|lint_id: &LintId| (*lint_id, level, span)) @@ -729,7 +729,7 @@ impl<'a, 'tcx> IdVisitingOperation for Context<'a, 'tcx> { None => {} Some(lints) => { for (lint_id, span, msg) in lints { - self.span_lint(lint_id.lint, span, &msg[]) + self.span_lint(lint_id.lint, span, &msg[..]) } } } diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 0871c36d892c6..d48a404176ace 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -183,7 +183,7 @@ impl<'a> CrateReader<'a> { let name = match *path_opt { Some((ref path_str, _)) => { let name = path_str.to_string(); - validate_crate_name(Some(self.sess), &name[], + validate_crate_name(Some(self.sess), &name[..], Some(i.span)); name } @@ -321,7 +321,7 @@ impl<'a> CrateReader<'a> { let source = self.sess.cstore.get_used_crate_source(cnum).unwrap(); if let Some(locs) = self.sess.opts.externs.get(name) { let found = locs.iter().any(|l| { - let l = fs::realpath(&Path::new(&l[])).ok(); + let l = fs::realpath(&Path::new(&l[..])).ok(); source.dylib.as_ref().map(|p| &p.0) == l.as_ref() || source.rlib.as_ref().map(|p| &p.0) == l.as_ref() }); @@ -459,8 +459,8 @@ impl<'a> CrateReader<'a> { let mut load_ctxt = loader::Context { sess: self.sess, span: span, - ident: &ident[], - crate_name: &name[], + ident: &ident[..], + crate_name: &name[..], hash: None, filesearch: self.sess.host_filesearch(PathKind::Crate), target: &self.sess.host, @@ -562,7 +562,7 @@ impl<'a> CrateReader<'a> { name, config::host_triple(), self.sess.opts.target_triple); - self.sess.span_err(span, &message[]); + self.sess.span_err(span, &message[..]); self.sess.abort_if_errors(); } @@ -575,7 +575,7 @@ impl<'a> CrateReader<'a> { let message = format!("plugin `{}` only found in rlib format, \ but must be available in dylib format", name); - self.sess.span_err(span, &message[]); + self.sess.span_err(span, &message[..]); // No need to abort because the loading code will just ignore this // empty dylib. None diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 3123fa31abdd1..5c18371e78892 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -163,7 +163,7 @@ fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) { rbml_w.end_tag(); rbml_w.start_tag(tag_mod_child); - rbml_w.wr_str(&s[]); + rbml_w.wr_str(&s[..]); rbml_w.end_tag(); } @@ -353,9 +353,9 @@ fn encode_enum_variant_info(ecx: &EncodeContext, let fields = ty::lookup_struct_fields(ecx.tcx, def_id); let idx = encode_info_for_struct(ecx, rbml_w, - &fields[], + &fields[..], index); - encode_struct_fields(rbml_w, &fields[], def_id); + encode_struct_fields(rbml_w, &fields[..], def_id); encode_index(rbml_w, idx, write_i64); } } @@ -1158,7 +1158,7 @@ fn encode_info_for_item(ecx: &EncodeContext, class itself */ let idx = encode_info_for_struct(ecx, rbml_w, - &fields[], + &fields[..], index); /* Index the class*/ @@ -1181,7 +1181,7 @@ fn encode_info_for_item(ecx: &EncodeContext, /* Encode def_ids for each field and method for methods, write all the stuff get_trait_method needs to know*/ - encode_struct_fields(rbml_w, &fields[], def_id); + encode_struct_fields(rbml_w, &fields[..], def_id); encode_inlined_item(ecx, rbml_w, IIItemRef(item)); diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 3158ccd076522..c743cb46c242c 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -322,7 +322,7 @@ impl<'a> Context<'a> { &Some(ref r) => format!("{} which `{}` depends on", message, r.ident) }; - self.sess.span_err(self.span, &message[]); + self.sess.span_err(self.span, &message[..]); if self.rejected_via_triple.len() > 0 { let mismatches = self.rejected_via_triple.iter(); @@ -404,7 +404,7 @@ impl<'a> Context<'a> { None => return FileDoesntMatch, Some(file) => file, }; - let (hash, rlib) = if file.starts_with(&rlib_prefix[]) && + let (hash, rlib) = if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") { (&file[(rlib_prefix.len()) .. (file.len() - ".rlib".len())], true) @@ -413,7 +413,7 @@ impl<'a> Context<'a> { (&file[(dylib_prefix.len()) .. (file.len() - dypair.1.len())], false) } else { - if file.starts_with(&staticlib_prefix[]) && + if file.starts_with(&staticlib_prefix[..]) && file.ends_with(".a") { staticlibs.push(CrateMismatch { path: path.clone(), @@ -627,7 +627,7 @@ impl<'a> Context<'a> { let mut rlibs = HashMap::new(); let mut dylibs = HashMap::new(); { - let locs = locs.iter().map(|l| Path::new(&l[])).filter(|loc| { + let locs = locs.iter().map(|l| Path::new(&l[..])).filter(|loc| { if !loc.exists() { sess.err(&format!("extern location for {} does not exist: {}", self.crate_name, loc.display())[]); @@ -645,8 +645,8 @@ impl<'a> Context<'a> { return true } else { let (ref prefix, ref suffix) = dylibname; - if file.starts_with(&prefix[]) && - file.ends_with(&suffix[]) { + if file.starts_with(&prefix[..]) && + file.ends_with(&suffix[..]) { return true } } diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 94654b849229a..5805725a8fc8b 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -641,7 +641,7 @@ fn parse_abi_set(st: &mut PState) -> abi::Abi { assert_eq!(next(st), '['); scan(st, |c| c == ']', |bytes| { let abi_str = str::from_utf8(bytes).unwrap(); - abi::lookup(&abi_str[]).expect(abi_str) + abi::lookup(&abi_str[..]).expect(abi_str) }) } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index c3302debdfaff..ae10eb686b010 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -134,7 +134,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, // Do an Option dance to use the path after it is moved below. let s = ast_map::path_to_string(path.iter().cloned()); path_as_str = Some(s); - path_as_str.as_ref().map(|x| &x[]) + path_as_str.as_ref().map(|x| &x[..]) }); let mut ast_dsr = reader::Decoder::new(ast_doc); let from_id_range = Decodable::decode(&mut ast_dsr).unwrap(); diff --git a/src/librustc/middle/cfg/graphviz.rs b/src/librustc/middle/cfg/graphviz.rs index 1f0fe4f1acaea..46b4a51c9d6fe 100644 --- a/src/librustc/middle/cfg/graphviz.rs +++ b/src/librustc/middle/cfg/graphviz.rs @@ -92,7 +92,7 @@ impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> { let s = replace_newline_with_backslash_l(s); label.push_str(&format!("exiting scope_{} {}", i, - &s[])[]); + &s[..])[]); } dot::LabelText::EscStr(label.into_cow()) } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 03456f8529028..60af99b36b85b 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -200,7 +200,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) { } // Fourth, check for unreachable arms. - check_arms(cx, &inlined_arms[], source); + check_arms(cx, &inlined_arms[..], source); // Finally, check if the whole match expression is exhaustive. // Check for empty enum, because is_useful only works on inhabited types. @@ -291,7 +291,7 @@ fn check_arms(cx: &MatchCheckCtxt, for pat in pats { let v = vec![&**pat]; - match is_useful(cx, &seen, &v[], LeaveOutWitness) { + match is_useful(cx, &seen, &v[..], LeaveOutWitness) { NotUseful => { match source { ast::MatchSource::IfLetDesugar { .. } => { @@ -351,7 +351,7 @@ fn raw_pat<'a>(p: &'a Pat) -> &'a Pat { fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast::MatchSource) { match is_useful(cx, matrix, &[DUMMY_WILD_PAT], ConstructWitness) { UsefulWithWitness(pats) => { - let witness = match &pats[] { + let witness = match &pats[..] { [ref witness] => &**witness, [] => DUMMY_WILD_PAT, _ => unreachable!() @@ -360,7 +360,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast: ast::MatchSource::ForLoopDesugar => { // `witness` has the form `Some()`, peel off the `Some` let witness = match witness.node { - ast::PatEnum(_, Some(ref pats)) => match &pats[] { + ast::PatEnum(_, Some(ref pats)) => match &pats[..] { [ref pat] => &**pat, _ => unreachable!(), }, @@ -664,7 +664,7 @@ fn is_useful(cx: &MatchCheckCtxt, UsefulWithWitness(pats) => UsefulWithWitness({ let arity = constructor_arity(cx, &c, left_ty); let mut result = { - let pat_slice = &pats[]; + let pat_slice = &pats[..]; let subpats: Vec<_> = (0..arity).map(|i| { pat_slice.get(i).map_or(DUMMY_WILD_PAT, |p| &**p) }).collect(); @@ -711,10 +711,10 @@ fn is_useful_specialized(cx: &MatchCheckCtxt, &Matrix(ref m): &Matrix, witness: WitnessPreference) -> Usefulness { let arity = constructor_arity(cx, &ctor, lty); let matrix = Matrix(m.iter().filter_map(|r| { - specialize(cx, &r[], &ctor, 0, arity) + specialize(cx, &r[..], &ctor, 0, arity) }).collect()); match specialize(cx, v, &ctor, 0, arity) { - Some(v) => is_useful(cx, &matrix, &v[], witness), + Some(v) => is_useful(cx, &matrix, &v[..], witness), None => NotUseful } } diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 3d03cd946c48f..6dfd781fa0884 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -62,7 +62,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt, None => None, Some(ast_map::NodeItem(it)) => match it.node { ast::ItemEnum(ast::EnumDef { ref variants }, _) => { - variant_expr(&variants[], variant_def.node) + variant_expr(&variants[..], variant_def.node) } _ => None }, @@ -83,7 +83,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt, // NOTE this doesn't do the right thing, it compares inlined // NodeId's to the original variant_def's NodeId, but they // come from different crates, so they will likely never match. - variant_expr(&variants[], variant_def.node).map(|e| e.id) + variant_expr(&variants[..], variant_def.node).map(|e| e.id) } _ => None }, @@ -209,7 +209,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P pub fn eval_const_expr(tcx: &ty::ctxt, e: &Expr) -> const_val { match eval_const_expr_partial(tcx, e, None) { Ok(r) => r, - Err(s) => tcx.sess.span_fatal(e.span, &s[]) + Err(s) => tcx.sess.span_fatal(e.span, &s[..]) } } @@ -552,14 +552,14 @@ pub fn compare_lit_exprs<'tcx>(tcx: &ty::ctxt<'tcx>, let a = match eval_const_expr_partial(tcx, a, ty_hint) { Ok(a) => a, Err(s) => { - tcx.sess.span_err(a.span, &s[]); + tcx.sess.span_err(a.span, &s[..]); return None; } }; let b = match eval_const_expr_partial(tcx, b, ty_hint) { Ok(b) => b, Err(s) => { - tcx.sess.span_err(b.span, &s[]); + tcx.sess.span_err(b.span, &s[..]); return None; } }; diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index b792a44d4d89a..37cd348e4185a 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -312,7 +312,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { let mut t = on_entry.to_vec(); self.apply_gen_kill(cfgidx, &mut t); temp_bits = t; - &temp_bits[] + &temp_bits[..] } }; debug!("{} each_bit_for_node({:?}, cfgidx={:?}) bits={}", @@ -421,7 +421,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { let bits = &mut self.kills[start.. end]; debug!("{} add_kills_from_flow_exits flow_exit={:?} bits={} [before]", self.analysis_name, flow_exit, mut_bits_to_string(bits)); - bits.clone_from_slice(&orig_kills[]); + bits.clone_from_slice(&orig_kills[..]); debug!("{} add_kills_from_flow_exits flow_exit={:?} bits={} [after]", self.analysis_name, flow_exit, mut_bits_to_string(bits)); } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index b2335f91ad986..ff78deb8d12ea 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -321,7 +321,7 @@ fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool { for attr in lint::gather_attrs(attrs) { match attr { Ok((ref name, lint::Allow, _)) - if &name[] == dead_code => return true, + if &name[..] == dead_code => return true, _ => (), } } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 5cc7502b5128d..39a27cb95f1a3 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -1166,7 +1166,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { let msg = format!("Pattern has unexpected def: {:?} and type {}", def, cmt_pat.ty.repr(tcx)); - tcx.sess.span_bug(pat.span, &msg[]) + tcx.sess.span_bug(pat.span, &msg[..]) } } } diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index daa820f43b57e..70b444d81d81f 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -142,7 +142,7 @@ pub trait Combine<'tcx> : Sized { for _ in a_regions { invariance.push(ty::Invariant); } - &invariance[] + &invariance[..] } }; diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 72b33613c66aa..f4b9f20988d53 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -200,9 +200,9 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { ref trace_origins, ref same_regions) => { if !same_regions.is_empty() { - self.report_processed_errors(&var_origins[], - &trace_origins[], - &same_regions[]); + self.report_processed_errors(&var_origins[..], + &trace_origins[..], + &same_regions[..]); } } } @@ -824,7 +824,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { let parent = self.tcx.map.get_parent(scope_id); let parent_node = self.tcx.map.find(parent); let taken = lifetimes_in_scope(self.tcx, scope_id); - let life_giver = LifeGiver::with_taken(&taken[]); + let life_giver = LifeGiver::with_taken(&taken[..]); let node_inner = match parent_node { Some(ref node) => match *node { ast_map::NodeItem(ref item) => { @@ -942,7 +942,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { } expl_self_opt = self.rebuild_expl_self(expl_self_opt, lifetime, &anon_nums, ®ion_names); - inputs = self.rebuild_args_ty(&inputs[], lifetime, + inputs = self.rebuild_args_ty(&inputs[..], lifetime, &anon_nums, ®ion_names); output = self.rebuild_output(&output, lifetime, &anon_nums, ®ion_names); ty_params = self.rebuild_ty_params(ty_params, lifetime, @@ -1426,7 +1426,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { opt_explicit_self, generics); let msg = format!("consider using an explicit lifetime \ parameter as shown: {}", suggested_fn); - self.tcx.sess.span_help(span, &msg[]); + self.tcx.sess.span_help(span, &msg[..]); } fn report_inference_failure(&self, @@ -1771,7 +1771,7 @@ impl LifeGiver { s.push_str(&num_to_string(self.counter.get())[]); if !self.taken.contains(&s) { lifetime = name_to_dummy_lifetime( - token::str_to_ident(&s[]).name); + token::str_to_ident(&s[..]).name); self.generated.borrow_mut().push(lifetime); break; } diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index 5cdfdcc7c9b6c..b4fd34f206fa7 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -977,7 +977,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { self.expansion(&mut var_data); self.contraction(&mut var_data); let values = - self.extract_values_and_collect_conflicts(&var_data[], + self.extract_values_and_collect_conflicts(&var_data[..], errors); self.collect_concrete_region_errors(&values, errors); values diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index e13a5672778e2..51342e0827487 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -149,7 +149,7 @@ impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> { fn visit_item(&mut self, item: &ast::Item) { match extract(&item.attrs) { Some(value) => { - let item_index = self.item_refs.get(&value[]).map(|x| *x); + let item_index = self.item_refs.get(&value[..]).map(|x| *x); match item_index { Some(item_index) => { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index d4fe09793131f..e58136fb3f4e4 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1119,7 +1119,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // Uninteresting cases: just propagate in rev exec order ast::ExprVec(ref exprs) => { - self.propagate_through_exprs(&exprs[], succ) + self.propagate_through_exprs(&exprs[..], succ) } ast::ExprRepeat(ref element, ref count) => { @@ -1143,7 +1143,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } else { succ }; - let succ = self.propagate_through_exprs(&args[], succ); + let succ = self.propagate_through_exprs(&args[..], succ); self.propagate_through_expr(&**f, succ) } @@ -1156,11 +1156,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } else { succ }; - self.propagate_through_exprs(&args[], succ) + self.propagate_through_exprs(&args[..], succ) } ast::ExprTup(ref exprs) => { - self.propagate_through_exprs(&exprs[], succ) + self.propagate_through_exprs(&exprs[..], succ) } ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op.node) => { diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 061557eb7dccd..baa1f5dc5a5cd 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -998,7 +998,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let all_bounds = util::transitive_bounds( - self.tcx(), &caller_trait_refs[]); + self.tcx(), &caller_trait_refs[..]); let matching_bounds = all_bounds.filter( diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8618bde95fe6f..9742accbf079a 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2331,7 +2331,7 @@ impl ClosureKind { }; match result { Ok(trait_did) => trait_did, - Err(err) => cx.sess.fatal(&err[]), + Err(err) => cx.sess.fatal(&err[..]), } } } @@ -2661,7 +2661,7 @@ impl FlagComputation { } &ty_tup(ref ts) => { - self.add_tys(&ts[]); + self.add_tys(&ts[..]); } &ty_bare_fn(_, ref f) => { @@ -3447,7 +3447,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { ty_struct(did, substs) => { let flds = struct_fields(cx, did, substs); let mut res = - TypeContents::union(&flds[], + TypeContents::union(&flds[..], |f| tc_mt(cx, f.mt, cache)); if !lookup_repr_hints(cx, did).contains(&attr::ReprExtern) { @@ -3470,14 +3470,14 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { } ty_tup(ref tys) => { - TypeContents::union(&tys[], + TypeContents::union(&tys[..], |ty| tc_ty(cx, *ty, cache)) } ty_enum(did, substs) => { let variants = substd_enum_variants(cx, did, substs); let mut res = - TypeContents::union(&variants[], |variant| { + TypeContents::union(&variants[..], |variant| { TypeContents::union(&variant.args[], |arg_ty| { tc_ty(cx, *arg_ty, cache) @@ -4940,7 +4940,7 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) match item.node { ItemTrait(_, _, _, ref ms) => { let (_, p) = - ast_util::split_trait_methods(&ms[]); + ast_util::split_trait_methods(&ms[..]); p.iter() .map(|m| { match impl_or_trait_item( @@ -6625,7 +6625,7 @@ pub fn with_freevars(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where { match tcx.freevars.borrow().get(&fid) { None => f(&[]), - Some(d) => f(&d[]) + Some(d) => f(&d[..]) } } diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index ee3fd681a0052..60a9ffc7d2e13 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -55,7 +55,7 @@ pub fn check_crate(krate: &ast::Crate, pub fn link_name(attrs: &[ast::Attribute]) -> Option { lang_items::extract(attrs).and_then(|name| { - $(if &name[] == stringify!($name) { + $(if &name[..] == stringify!($name) { Some(InternedString::new(stringify!($sym))) } else)* { None diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs index 1895cbcb5421e..b3bc898748fdc 100644 --- a/src/librustc/plugin/load.rs +++ b/src/librustc/plugin/load.rs @@ -111,19 +111,19 @@ impl<'a> PluginLoader<'a> { // inside this crate, so continue would spew "macro undefined" // errors Err(err) => { - self.sess.span_fatal(span, &err[]) + self.sess.span_fatal(span, &err[..]) } }; unsafe { let registrar = - match lib.symbol(&symbol[]) { + match lib.symbol(&symbol[..]) { Ok(registrar) => { mem::transmute::<*mut u8,PluginRegistrarFun>(registrar) } // again fatal if we can't register macros Err(err) => { - self.sess.span_fatal(span, &err[]) + self.sess.span_fatal(span, &err[..]) } }; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 5768539b2cd76..93a25de0491fe 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -629,7 +629,7 @@ pub fn build_configuration(sess: &Session) -> ast::CrateConfig { append_configuration(&mut user_cfg, InternedString::new("test")) } let mut v = user_cfg.into_iter().collect::>(); - v.push_all(&default_cfg[]); + v.push_all(&default_cfg[..]); v } @@ -824,7 +824,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec ) -> ast::CrateConfig { pub fn build_session_options(matches: &getopts::Matches) -> Options { let unparsed_crate_types = matches.opt_strs("crate-type"); let crate_types = parse_crate_types_from_list(unparsed_crate_types) - .unwrap_or_else(|e| early_error(&e[])); + .unwrap_or_else(|e| early_error(&e[..])); let mut lint_opts = vec!(); let mut describe_lints = false; @@ -923,7 +923,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let mut search_paths = SearchPaths::new(); for s in &matches.opt_strs("L") { - search_paths.add_path(&s[]); + search_paths.add_path(&s[..]); } let libs = matches.opt_strs("l").into_iter().map(|s| { @@ -981,7 +981,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { --debuginfo"); } - let color = match matches.opt_str("color").as_ref().map(|s| &s[]) { + let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) { Some("auto") => Auto, Some("always") => Always, Some("never") => Never, @@ -1119,7 +1119,7 @@ mod test { let sessopts = build_session_options(matches); let sess = build_session(sessopts, None, registry); let cfg = build_configuration(&sess); - assert!((attr::contains_name(&cfg[], "test"))); + assert!((attr::contains_name(&cfg[..], "test"))); } // When the user supplies --test and --cfg test, don't implicitly add diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index bd44dbe78f543..c1c5518887577 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -75,13 +75,13 @@ impl Session { } pub fn span_err(&self, sp: Span, msg: &str) { match split_msg_into_multilines(msg) { - Some(msg) => self.diagnostic().span_err(sp, &msg[]), + Some(msg) => self.diagnostic().span_err(sp, &msg[..]), None => self.diagnostic().span_err(sp, msg) } } pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) { match split_msg_into_multilines(msg) { - Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[], code), + Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[..], code), None => self.diagnostic().span_err_with_code(sp, msg, code) } } diff --git a/src/librustc/util/lev_distance.rs b/src/librustc/util/lev_distance.rs index ca1bb7d7a9404..10a7b2abea80b 100644 --- a/src/librustc/util/lev_distance.rs +++ b/src/librustc/util/lev_distance.rs @@ -48,7 +48,7 @@ fn test_lev_distance() { for c in (0u32..MAX as u32) .filter_map(|i| from_u32(i)) .map(|i| i.to_string()) { - assert_eq!(lev_distance(&c[], &c[]), 0); + assert_eq!(lev_distance(&c[..], &c[..]), 0); } let a = "\nMäry häd ä little lämb\n\nLittle lämb\n"; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 426101e858a89..7dd25e9dc1950 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -292,7 +292,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String { Some(def_id) => { s.push_str(" {"); let path_str = ty::item_path_str(cx, def_id); - s.push_str(&path_str[]); + s.push_str(&path_str[..]); s.push_str("}"); } None => { } @@ -376,7 +376,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String { .iter() .map(|elem| ty_to_string(cx, *elem)) .collect::>(); - match &strs[] { + match &strs[..] { [ref string] => format!("({},)", string), strs => format!("({})", strs.connect(", ")) } @@ -625,7 +625,7 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for [T] { impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for OwnedSlice { fn repr(&self, tcx: &ctxt<'tcx>) -> String { - repr_vec(tcx, &self[]) + repr_vec(tcx, &self[..]) } } @@ -633,7 +633,7 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for OwnedSlice { // autoderef cannot convert the &[T] handler impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Vec { fn repr(&self, tcx: &ctxt<'tcx>) -> String { - repr_vec(tcx, &self[]) + repr_vec(tcx, &self[..]) } } @@ -673,7 +673,7 @@ impl<'tcx> UserString<'tcx> for TraitAndProjections<'tcx> { &base, trait_ref.substs, trait_ref.def_id, - &projection_bounds[], + &projection_bounds[..], || ty::lookup_trait_def(tcx, trait_ref.def_id).generics.clone()) } } @@ -1259,7 +1259,7 @@ impl<'tcx, T> UserString<'tcx> for ty::Binder } }) }); - let names: Vec<_> = names.iter().map(|s| &s[]).collect(); + let names: Vec<_> = names.iter().map(|s| &s[..]).collect(); let value_str = unbound_value.user_string(tcx); if names.len() == 0 { diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index b779963a21917..c45ee258342ec 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -53,7 +53,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option, args: &str, cwd: Option<&Path>, paths: &[&Path]) -> ProcessOutput { let ar = match *maybe_ar_prog { - Some(ref ar) => &ar[], + Some(ref ar) => &ar[..], None => "ar" }; let mut cmd = Command::new(ar); @@ -84,7 +84,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option, o }, Err(e) => { - handler.err(&format!("could not exec `{}`: {}", &ar[], + handler.err(&format!("could not exec `{}`: {}", &ar[..], e)[]); handler.abort_if_errors(); panic!("rustc::back::archive::run_ar() should not reach this point"); @@ -101,10 +101,10 @@ pub fn find_library(name: &str, osprefix: &str, ossuffix: &str, for path in search_paths { debug!("looking for {} inside {:?}", name, path.display()); - let test = path.join(&oslibname[]); + let test = path.join(&oslibname[..]); if test.exists() { return test } if oslibname != unixlibname { - let test = path.join(&unixlibname[]); + let test = path.join(&unixlibname[..]); if test.exists() { return test } } } @@ -192,12 +192,12 @@ impl<'a> ArchiveBuilder<'a> { // as simple comparison is not enough - there // might be also an extra name suffix let obj_start = format!("{}", name); - let obj_start = &obj_start[]; + let obj_start = &obj_start[..]; // Ignoring all bytecode files, no matter of // name let bc_ext = ".bytecode.deflate"; - self.add_archive(rlib, &name[], |fname: &str| { + self.add_archive(rlib, &name[..], |fname: &str| { let skip_obj = lto && fname.starts_with(obj_start) && fname.ends_with(".o"); skip_obj || fname.ends_with(bc_ext) || fname == METADATA_FILENAME @@ -234,7 +234,7 @@ impl<'a> ArchiveBuilder<'a> { // allow running `ar s file.a` to update symbols only. if self.should_update_symbols { run_ar(self.archive.handler, &self.archive.maybe_ar_prog, - "s", Some(self.work_dir.path()), &args[]); + "s", Some(self.work_dir.path()), &args[..]); } return self.archive; } @@ -254,7 +254,7 @@ impl<'a> ArchiveBuilder<'a> { // Add the archive members seen so far, without updating the // symbol table (`S`). run_ar(self.archive.handler, &self.archive.maybe_ar_prog, - "cruS", Some(self.work_dir.path()), &args[]); + "cruS", Some(self.work_dir.path()), &args[..]); args.clear(); args.push(&abs_dst); @@ -269,7 +269,7 @@ impl<'a> ArchiveBuilder<'a> { // necessary. let flags = if self.should_update_symbols { "crus" } else { "cruS" }; run_ar(self.archive.handler, &self.archive.maybe_ar_prog, - flags, Some(self.work_dir.path()), &args[]); + flags, Some(self.work_dir.path()), &args[..]); self.archive } @@ -312,7 +312,7 @@ impl<'a> ArchiveBuilder<'a> { } else { filename }; - let new_filename = self.work_dir.path().join(&filename[]); + let new_filename = self.work_dir.path().join(&filename[..]); try!(fs::rename(file, &new_filename)); self.members.push(Path::new(filename)); } diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs index 36bbd4b987297..21e4f55ffa794 100644 --- a/src/librustc_back/rpath.rs +++ b/src/librustc_back/rpath.rs @@ -44,8 +44,8 @@ pub fn get_rpath_flags(config: RPathConfig) -> Vec where l.map(|p| p.clone()) }).collect::>(); - let rpaths = get_rpaths(config, &libs[]); - flags.push_all(&rpaths_to_flags(&rpaths[])[]); + let rpaths = get_rpaths(config, &libs[..]); + flags.push_all(&rpaths_to_flags(&rpaths[..])[]); flags } @@ -82,14 +82,14 @@ fn get_rpaths(mut config: RPathConfig, libs: &[Path]) -> Vec } } - log_rpaths("relative", &rel_rpaths[]); - log_rpaths("fallback", &fallback_rpaths[]); + log_rpaths("relative", &rel_rpaths[..]); + log_rpaths("fallback", &fallback_rpaths[..]); let mut rpaths = rel_rpaths; - rpaths.push_all(&fallback_rpaths[]); + rpaths.push_all(&fallback_rpaths[..]); // Remove duplicates - let rpaths = minimize_rpaths(&rpaths[]); + let rpaths = minimize_rpaths(&rpaths[..]); return rpaths; } @@ -139,7 +139,7 @@ fn minimize_rpaths(rpaths: &[String]) -> Vec { let mut set = HashSet::new(); let mut minimized = Vec::new(); for rpath in rpaths { - if set.insert(&rpath[]) { + if set.insert(&rpath[..]) { minimized.push(rpath.clone()); } } diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 692e6b474fd27..01a5f0d6e20f8 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -254,18 +254,18 @@ impl Target { macro_rules! key { ($key_name:ident) => ( { let name = (stringify!($key_name)).replace("_", "-"); - obj.find(&name[]).map(|o| o.as_string() + obj.find(&name[..]).map(|o| o.as_string() .map(|s| base.options.$key_name = s.to_string())); } ); ($key_name:ident, bool) => ( { let name = (stringify!($key_name)).replace("_", "-"); - obj.find(&name[]) + obj.find(&name[..]) .map(|o| o.as_boolean() .map(|s| base.options.$key_name = s)); } ); ($key_name:ident, list) => ( { let name = (stringify!($key_name)).replace("_", "-"); - obj.find(&name[]).map(|o| o.as_array() + obj.find(&name[..]).map(|o| o.as_array() .map(|v| base.options.$key_name = v.iter() .map(|a| a.as_string().unwrap().to_string()).collect() ) diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index a18e8b16e8bac..abe01d193b492 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -656,7 +656,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { &self.bccx.loan_path_to_string(move_path)[]) }; - self.bccx.span_err(span, &err_message[]); + self.bccx.span_err(span, &err_message[..]); self.bccx.span_note( loan_span, &format!("borrow of `{}` occurs here", diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs index bee1ada28e314..c873831cb0f65 100644 --- a/src/librustc_borrowck/borrowck/fragments.rs +++ b/src/librustc_borrowck/borrowck/fragments.rs @@ -38,7 +38,7 @@ enum Fragment { // This represents the collection of all but one of the elements // from an array at the path described by the move path index. // Note that attached MovePathIndex should have mem_categorization - // of InteriorElement (i.e. array dereference `&foo[]`). + // of InteriorElement (i.e. array dereference `&foo[..]`). AllButOneFrom(MovePathIndex), } @@ -198,11 +198,11 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) { // First, filter out duplicates moved.sort(); moved.dedup(); - debug!("fragments 1 moved: {:?}", path_lps(&moved[])); + debug!("fragments 1 moved: {:?}", path_lps(&moved[..])); assigned.sort(); assigned.dedup(); - debug!("fragments 1 assigned: {:?}", path_lps(&assigned[])); + debug!("fragments 1 assigned: {:?}", path_lps(&assigned[..])); // Second, build parents from the moved and assigned. for m in &moved { @@ -222,14 +222,14 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) { parents.sort(); parents.dedup(); - debug!("fragments 2 parents: {:?}", path_lps(&parents[])); + debug!("fragments 2 parents: {:?}", path_lps(&parents[..])); // Third, filter the moved and assigned fragments down to just the non-parents - moved.retain(|f| non_member(*f, &parents[])); - debug!("fragments 3 moved: {:?}", path_lps(&moved[])); + moved.retain(|f| non_member(*f, &parents[..])); + debug!("fragments 3 moved: {:?}", path_lps(&moved[..])); - assigned.retain(|f| non_member(*f, &parents[])); - debug!("fragments 3 assigned: {:?}", path_lps(&assigned[])); + assigned.retain(|f| non_member(*f, &parents[..])); + debug!("fragments 3 assigned: {:?}", path_lps(&assigned[..])); // Fourth, build the leftover from the moved, assigned, and parents. for m in &moved { @@ -247,16 +247,16 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) { unmoved.sort(); unmoved.dedup(); - debug!("fragments 4 unmoved: {:?}", frag_lps(&unmoved[])); + debug!("fragments 4 unmoved: {:?}", frag_lps(&unmoved[..])); // Fifth, filter the leftover fragments down to its core. unmoved.retain(|f| match *f { AllButOneFrom(_) => true, - Just(mpi) => non_member(mpi, &parents[]) && - non_member(mpi, &moved[]) && - non_member(mpi, &assigned[]) + Just(mpi) => non_member(mpi, &parents[..]) && + non_member(mpi, &moved[..]) && + non_member(mpi, &assigned[..]) }); - debug!("fragments 5 unmoved: {:?}", frag_lps(&unmoved[])); + debug!("fragments 5 unmoved: {:?}", frag_lps(&unmoved[..])); // Swap contents back in. fragments.unmoved_fragments = unmoved; @@ -437,7 +437,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>, let msg = format!("type {} ({:?}) is not fragmentable", parent_ty.repr(tcx), sty_and_variant_info); let opt_span = origin_id.and_then(|id|tcx.map.opt_span(id)); - tcx.sess.opt_span_bug(opt_span, &msg[]) + tcx.sess.opt_span_bug(opt_span, &msg[..]) } } } diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 93d97a054a4b3..518e4bc472ca4 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -137,7 +137,7 @@ fn borrowck_fn(this: &mut BorrowckCtxt, check_loans::check_loans(this, &loan_dfcx, flowed_moves, - &all_loans[], + &all_loans[..], id, decl, body); diff --git a/src/librustc_borrowck/graphviz.rs b/src/librustc_borrowck/graphviz.rs index 56bf3ae7fd5a3..39c9d9ba6ad24 100644 --- a/src/librustc_borrowck/graphviz.rs +++ b/src/librustc_borrowck/graphviz.rs @@ -89,7 +89,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> { set.push_str(", "); } let loan_str = self.borrowck_ctxt.loan_path_to_string(&*lp); - set.push_str(&loan_str[]); + set.push_str(&loan_str[..]); saw_some = true; true }); diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 728ff64759998..a260997f60594 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -85,7 +85,7 @@ pub fn compile_input(sess: Session, let expanded_crate = match phase_2_configure_and_expand(&sess, krate, - &id[], + &id[..], addl_plugins) { None => return, Some(k) => k @@ -99,20 +99,20 @@ pub fn compile_input(sess: Session, &sess, outdir, &expanded_crate, - &id[])); + &id[..])); let mut forest = ast_map::Forest::new(expanded_crate); let arenas = ty::CtxtArenas::new(); let ast_map = assign_node_ids_and_map(&sess, &mut forest); - write_out_deps(&sess, input, &outputs, &id[]); + write_out_deps(&sess, input, &outputs, &id[..]); controller_entry_point!(after_write_deps, CompileState::state_after_write_deps(input, &sess, outdir, &ast_map, - &id[])); + &id[..])); let analysis = phase_3_run_analysis_passes(sess, ast_map, diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index ac91a0098ea75..2550432c8101a 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -272,7 +272,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { -> Compilation { match matches.opt_str("explain") { Some(ref code) => { - match descriptions.find_description(&code[]) { + match descriptions.find_description(&code[..]) { Some(ref description) => { println!("{}", description); } @@ -582,7 +582,7 @@ Available lint options: for lint in lints { let name = lint.name_lower().replace("_", "-"); println!(" {} {:7.7} {}", - padded(&name[]), lint.default_level.as_str(), lint.desc); + padded(&name[..]), lint.default_level.as_str(), lint.desc); } println!("\n"); }; @@ -612,7 +612,7 @@ Available lint options: let desc = to.into_iter().map(|x| x.as_str().replace("_", "-")) .collect::>().connect(", "); println!(" {} {}", - padded(&name[]), desc); + padded(&name[..]), desc); } println!("\n"); }; @@ -678,7 +678,7 @@ pub fn handle_options(mut args: Vec) -> Option { } let matches = - match getopts::getopts(&args[], &config::optgroups()[]) { + match getopts::getopts(&args[..], &config::optgroups()[]) { Ok(m) => m, Err(f_stable_attempt) => { // redo option parsing, including unstable options this time, @@ -803,7 +803,7 @@ pub fn monitor(f: F) { "run with `RUST_BACKTRACE=1` for a backtrace".to_string(), ]; for note in &xs { - emitter.emit(None, ¬e[], None, diagnostic::Note) + emitter.emit(None, ¬e[..], None, diagnostic::Note) } match r.read_to_string() { diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 5dfef6c775e1e..0fbfa5fd89dd7 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -383,7 +383,7 @@ impl UserIdentifiedItem { ItemViaNode(node_id) => NodesMatchingDirect(Some(node_id).into_iter()), ItemViaPath(ref parts) => - NodesMatchingSuffix(map.nodes_matching_suffix(&parts[])), + NodesMatchingSuffix(map.nodes_matching_suffix(&parts[..])), } } @@ -395,7 +395,7 @@ impl UserIdentifiedItem { user_option, self.reconstructed_input(), is_wrong_because); - sess.fatal(&message[]) + sess.fatal(&message[..]) }; let mut saw_node = ast::DUMMY_NODE_ID; @@ -522,7 +522,7 @@ pub fn pretty_print_input(sess: Session, let is_expanded = needs_expansion(&ppm); let compute_ast_map = needs_ast_map(&ppm, &opt_uii); let krate = if compute_ast_map { - match driver::phase_2_configure_and_expand(&sess, krate, &id[], None) { + match driver::phase_2_configure_and_expand(&sess, krate, &id[..], None) { None => return, Some(k) => k } @@ -541,7 +541,7 @@ pub fn pretty_print_input(sess: Session, }; let src_name = driver::source_name(input); - let src = sess.codemap().get_filemap(&src_name[]) + let src = sess.codemap().get_filemap(&src_name[..]) .src.as_bytes().to_vec(); let mut rdr = MemReader::new(src); @@ -632,8 +632,8 @@ pub fn pretty_print_input(sess: Session, // point to what was found, if there's an // accessible span. match ast_map.opt_span(nodeid) { - Some(sp) => sess.span_fatal(sp, &message[]), - None => sess.fatal(&message[]) + Some(sp) => sess.span_fatal(sp, &message[..]), + None => sess.fatal(&message[..]) } } } diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 7105a6cc48882..97ecb0b97e901 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -278,7 +278,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> { pub fn t_param(&self, space: subst::ParamSpace, index: u32) -> Ty<'tcx> { let name = format!("T{}", index); - ty::mk_param(self.infcx.tcx, space, index, token::intern(&name[])) + ty::mk_param(self.infcx.tcx, space, index, token::intern(&name[..])) } pub fn re_early_bound(&self, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 96e146fc894f9..5662a74a53d34 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -585,10 +585,10 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { match result { None => true, Some((span, msg, note)) => { - self.tcx.sess.span_err(span, &msg[]); + self.tcx.sess.span_err(span, &msg[..]); match note { Some((span, msg)) => { - self.tcx.sess.span_note(span, &msg[]) + self.tcx.sess.span_note(span, &msg[..]) } None => {}, } @@ -690,7 +690,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { UnnamedField(idx) => format!("field #{} of {} is private", idx + 1, struct_desc), }; - self.tcx.sess.span_err(span, &msg[]); + self.tcx.sess.span_err(span, &msg[..]); } // Given the ID of a method, checks to ensure it's in scope. diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 874c8f2a9402d..eba00ad484e32 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1072,7 +1072,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { &import_directive.module_path[], import_directive.subclass), help); - self.resolve_error(span, &msg[]); + self.resolve_error(span, &msg[..]); } Indeterminate => break, // Bail out. We'll come around next time. Success(()) => () // Good. Continue. @@ -1102,7 +1102,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .iter() .map(|seg| seg.identifier.name) .collect(); - self.names_to_string(&names[]) + self.names_to_string(&names[..]) } fn import_directive_subclass_to_string(&mut self, @@ -1166,7 +1166,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let module_path = &import_directive.module_path; debug!("(resolving import for module) resolving import `{}::...` in `{}`", - self.names_to_string(&module_path[]), + self.names_to_string(&module_path[..]), self.module_to_string(&*module_)); // First, resolve the module path for the directive, if necessary. @@ -1175,7 +1175,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some((self.graph_root.get_module(), LastMod(AllPublic))) } else { match self.resolve_module_path(module_.clone(), - &module_path[], + &module_path[..], DontUseLexicalScope, import_directive.span, ImportSearch) { @@ -1768,7 +1768,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ValueNS => "value", }, &token::get_name(name)); - span_err!(self.session, import_span, E0252, "{}", &msg[]); + span_err!(self.session, import_span, E0252, "{}", &msg[..]); } Some(_) | None => {} } @@ -1783,7 +1783,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) { let msg = format!("`{}` is not directly importable", token::get_name(name)); - span_err!(self.session, import_span, E0253, "{}", &msg[]); + span_err!(self.session, import_span, E0253, "{}", &msg[..]); } } @@ -1804,7 +1804,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { crate in this module \ (maybe you meant `use {0}::*`?)", &token::get_name(name)); - span_err!(self.session, import_span, E0254, "{}", &msg[]); + span_err!(self.session, import_span, E0254, "{}", &msg[..]); } Some(_) | None => {} } @@ -1826,7 +1826,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let msg = format!("import `{}` conflicts with value \ in this module", &token::get_name(name)); - span_err!(self.session, import_span, E0255, "{}", &msg[]); + span_err!(self.session, import_span, E0255, "{}", &msg[..]); if let Some(span) = value.value_span { self.session.span_note(span, "conflicting value here"); @@ -1844,7 +1844,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let msg = format!("import `{}` conflicts with type in \ this module", &token::get_name(name)); - span_err!(self.session, import_span, E0256, "{}", &msg[]); + span_err!(self.session, import_span, E0256, "{}", &msg[..]); if let Some(span) = ty.type_span { self.session.span_note(span, "note conflicting type here") @@ -1857,7 +1857,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let msg = format!("inherent implementations \ are only allowed on types \ defined in the current module"); - span_err!(self.session, span, E0257, "{}", &msg[]); + span_err!(self.session, span, E0257, "{}", &msg[..]); self.session.span_note(import_span, "import from other module here") } @@ -1866,7 +1866,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let msg = format!("import `{}` conflicts with existing \ submodule", &token::get_name(name)); - span_err!(self.session, import_span, E0258, "{}", &msg[]); + span_err!(self.session, import_span, E0258, "{}", &msg[..]); if let Some(span) = ty.type_span { self.session.span_note(span, "note conflicting module here") @@ -1953,7 +1953,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let segment_name = token::get_name(name); let module_name = self.module_to_string(&*search_module); let mut span = span; - let msg = if "???" == &module_name[] { + let msg = if "???" == &module_name[..] { span.hi = span.lo + Pos::from_usize(segment_name.len()); match search_parent_externals(name, @@ -2066,7 +2066,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match module_prefix_result { Failed(None) => { let mpath = self.names_to_string(module_path); - let mpath = &mpath[]; + let mpath = &mpath[..]; match mpath.rfind(':') { Some(idx) => { let msg = format!("Could not find `{}` in `{}`", @@ -2369,11 +2369,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let mut containing_module; let mut i; let first_module_path_string = token::get_name(module_path[0]); - if "self" == &first_module_path_string[] { + if "self" == &first_module_path_string[..] { containing_module = self.get_nearest_normal_module_parent_or_self(module_); i = 1; - } else if "super" == &first_module_path_string[] { + } else if "super" == &first_module_path_string[..] { containing_module = self.get_nearest_normal_module_parent_or_self(module_); i = 0; // We'll handle `super` below. @@ -2384,7 +2384,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Now loop through all the `super`s we find. while i < module_path.len() { let string = token::get_name(module_path[i]); - if "super" != &string[] { + if "super" != &string[..] { break } debug!("(resolving module prefix) resolving `super` at {}", @@ -2515,7 +2515,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } else { let err = format!("unresolved import (maybe you meant `{}::*`?)", sn); - self.resolve_error((*imports)[index].span, &err[]); + self.resolve_error((*imports)[index].span, &err[..]); } } @@ -2853,7 +2853,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { generics, implemented_traits, &**self_type, - &impl_items[]); + &impl_items[..]); } ItemTrait(_, ref generics, ref bounds, ref trait_items) => { @@ -3196,7 +3196,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }; let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str); - self.resolve_error(trait_reference.path.span, &msg[]); + self.resolve_error(trait_reference.path.span, &msg[..]); } Some(def) => { match def { @@ -3624,7 +3624,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { None => { let msg = format!("use of undeclared type name `{}`", self.path_names_to_string(path)); - self.resolve_error(ty.span, &msg[]); + self.resolve_error(ty.span, &msg[..]); } } } @@ -3825,7 +3825,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { def: {:?}", result); let msg = format!("`{}` does not name a structure", self.path_names_to_string(path)); - self.resolve_error(path.span, &msg[]); + self.resolve_error(path.span, &msg[..]); } } } @@ -4082,7 +4082,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let last_private; let module = self.current_module.clone(); match self.resolve_module_path(module, - &module_path[], + &module_path[..], UseLexicalScope, path.span, PathSearch) { @@ -4140,7 +4140,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let containing_module; let last_private; match self.resolve_module_path_from_root(root_module, - &module_path[], + &module_path[..], 0, path.span, PathSearch, @@ -4150,7 +4150,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some((span, msg)) => (span, msg), None => { let msg = format!("Use of undeclared module `::{}`", - self.names_to_string(&module_path[])); + self.names_to_string(&module_path[..])); (path.span, msg) } }; @@ -4309,7 +4309,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } else { match this.resolve_module_path(root, - &name_path[], + &name_path[..], UseLexicalScope, span, PathSearch) { @@ -4347,7 +4347,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::>(); // Look for a method in the current self type's impl module. - match get_module(self, path.span, &name_path[]) { + match get_module(self, path.span, &name_path[..]) { Some(module) => match module.children.borrow().get(&name) { Some(binding) => { let p_str = self.path_names_to_string(&path); @@ -4568,7 +4568,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { def: {:?}", result); let msg = format!("`{}` does not name a structure", self.path_names_to_string(path)); - self.resolve_error(path.span, &msg[]); + self.resolve_error(path.span, &msg[..]); } } diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 9f26e9182ab1e..ef849bb3dca05 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -127,7 +127,7 @@ pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input: &Input) -> String { let validate = |s: String, span: Option| { - creader::validate_crate_name(sess, &s[], span); + creader::validate_crate_name(sess, &s[..], span); s }; @@ -141,11 +141,11 @@ pub fn find_crate_name(sess: Option<&Session>, if let Some(sess) = sess { if let Some(ref s) = sess.opts.crate_name { if let Some((attr, ref name)) = attr_crate_name { - if *s != &name[] { + if *s != &name[..] { let msg = format!("--crate-name and #[crate_name] are \ required to match, but `{}` != `{}`", s, name); - sess.span_err(attr.span, &msg[]); + sess.span_err(attr.span, &msg[..]); } } return validate(s.clone(), None); @@ -195,7 +195,7 @@ fn symbol_hash<'tcx>(tcx: &ty::ctxt<'tcx>, symbol_hasher.input_str("-"); symbol_hasher.input_str(link_meta.crate_hash.as_str()); for meta in &*tcx.sess.crate_metadata.borrow() { - symbol_hasher.input_str(&meta[]); + symbol_hasher.input_str(&meta[..]); } symbol_hasher.input_str("-"); symbol_hasher.input_str(&encoder::encoded_ty(tcx, t)[]); @@ -262,7 +262,7 @@ pub fn sanitize(s: &str) -> String { if result.len() > 0 && result.as_bytes()[0] != '_' as u8 && ! (result.as_bytes()[0] as char).is_xid_start() { - return format!("_{}", &result[]); + return format!("_{}", &result[..]); } return result; @@ -331,17 +331,17 @@ pub fn mangle_exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, path: PathEl hash.push(EXTRA_CHARS.as_bytes()[extra2] as char); hash.push(EXTRA_CHARS.as_bytes()[extra3] as char); - exported_name(path, &hash[]) + exported_name(path, &hash[..]) } pub fn mangle_internal_name_by_type_and_seq<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>, name: &str) -> String { let s = ppaux::ty_to_string(ccx.tcx(), t); - let path = [PathName(token::intern(&s[])), + let path = [PathName(token::intern(&s[..])), gensym_name(name)]; let hash = get_symbol_hash(ccx, t); - mangle(path.iter().cloned(), Some(&hash[])) + mangle(path.iter().cloned(), Some(&hash[..])) } pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> String { @@ -541,7 +541,7 @@ fn link_rlib<'a>(sess: &'a Session, for &(ref l, kind) in &*sess.cstore.get_used_libraries().borrow() { match kind { cstore::NativeStatic => { - ab.add_native_library(&l[]).unwrap(); + ab.add_native_library(&l[..]).unwrap(); } cstore::NativeFramework | cstore::NativeUnknown => {} } @@ -619,7 +619,7 @@ fn link_rlib<'a>(sess: &'a Session, e)[]) }; - let bc_data_deflated = match flate::deflate_bytes(&bc_data[]) { + let bc_data_deflated = match flate::deflate_bytes(&bc_data[..]) { Some(compressed) => compressed, None => sess.fatal(&format!("failed to compress bytecode from {}", bc_filename.display())[]) @@ -678,7 +678,7 @@ fn write_rlib_bytecode_object_v1(writer: &mut T, try! { writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC) }; try! { writer.write_le_u32(1) }; try! { writer.write_le_u64(bc_data_deflated_size) }; - try! { writer.write_all(&bc_data_deflated[]) }; + try! { writer.write_all(&bc_data_deflated[..]) }; let number_of_bytes_written_so_far = RLIB_BYTECODE_OBJECT_MAGIC.len() + // magic id @@ -733,7 +733,7 @@ fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) { continue } }; - ab.add_rlib(&p, &name[], sess.lto()).unwrap(); + ab.add_rlib(&p, &name[..], sess.lto()).unwrap(); let native_libs = csearch::get_native_libraries(&sess.cstore, cnum); all_native_libs.extend(native_libs.into_iter()); @@ -769,7 +769,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool, // The invocations of cc share some flags across platforms let pname = get_cc_prog(sess); - let mut cmd = Command::new(&pname[]); + let mut cmd = Command::new(&pname[..]); cmd.args(&sess.target.target.options.pre_link_args[]); link_args(&mut cmd, sess, dylib, tmpdir.path(), @@ -798,7 +798,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool, sess.note(&format!("{:?}", &cmd)[]); let mut output = prog.error.clone(); output.push_all(&prog.output[]); - sess.note(str::from_utf8(&output[]).unwrap()); + sess.note(str::from_utf8(&output[..]).unwrap()); sess.abort_if_errors(); } debug!("linker stderr:\n{}", String::from_utf8(prog.error).unwrap()); @@ -868,7 +868,7 @@ fn link_args(cmd: &mut Command, let mut v = b"-Wl,-force_load,".to_vec(); v.push_all(morestack.as_vec()); - cmd.arg(&v[]); + cmd.arg(&v[..]); } else { cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]); } @@ -993,7 +993,7 @@ fn link_args(cmd: &mut Command, if sess.opts.cg.rpath { let mut v = "-Wl,-install_name,@rpath/".as_bytes().to_vec(); v.push_all(out_filename.filename().unwrap()); - cmd.arg(&v[]); + cmd.arg(&v[..]); } } else { cmd.arg("-shared"); @@ -1029,7 +1029,7 @@ fn link_args(cmd: &mut Command, // with any #[link_args] attributes found inside the crate let empty = Vec::new(); cmd.args(&sess.opts.cg.link_args.as_ref().unwrap_or(&empty)[]); - cmd.args(&used_link_args[]); + cmd.args(&used_link_args[..]); } // # Native library linking @@ -1086,14 +1086,14 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) { } else { // -force_load is the OSX equivalent of --whole-archive, but it // involves passing the full path to the library to link. - let lib = archive::find_library(&l[], + let lib = archive::find_library(&l[..], &sess.target.target.options.staticlib_prefix, &sess.target.target.options.staticlib_suffix, - &search_path[], + &search_path[..], &sess.diagnostic().handler); let mut v = b"-Wl,-force_load,".to_vec(); v.push_all(lib.as_vec()); - cmd.arg(&v[]); + cmd.arg(&v[..]); } } if takes_hints { @@ -1106,7 +1106,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) { cmd.arg(format!("-l{}", l)); } cstore::NativeFramework => { - cmd.arg("-framework").arg(&l[]); + cmd.arg("-framework").arg(&l[..]); } cstore::NativeStatic => unreachable!(), } @@ -1248,7 +1248,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, let mut v = "-l".as_bytes().to_vec(); v.push_all(unlib(&sess.target, cratepath.filestem().unwrap())); - cmd.arg(&v[]); + cmd.arg(&v[..]); } } @@ -1290,7 +1290,7 @@ fn add_upstream_native_libraries(cmd: &mut Command, sess: &Session) { } cstore::NativeFramework => { cmd.arg("-framework"); - cmd.arg(&lib[]); + cmd.arg(&lib[..]); } cstore::NativeStatic => { sess.bug("statics shouldn't be propagated"); diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index c88e76f427073..7c34fdd3ff898 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -132,7 +132,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, bc_decoded.len() as libc::size_t) { write::llvm_err(sess.diagnostic().handler(), format!("failed to load bc of `{}`", - &name[])); + &name[..])); } }); } diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 9934d9993d61d..c7d7942f774ff 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -47,14 +47,14 @@ pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! { unsafe { let cstr = llvm::LLVMRustGetLastError(); if cstr == ptr::null() { - handler.fatal(&msg[]); + handler.fatal(&msg[..]); } else { let err = ffi::c_str_to_bytes(&cstr); let err = String::from_utf8_lossy(err).to_string(); libc::free(cstr as *mut _); handler.fatal(&format!("{}: {}", - &msg[], - &err[])[]); + &msg[..], + &err[..])[]); } } } @@ -105,7 +105,7 @@ impl SharedEmitter { Some(ref code) => { handler.emit_with_code(None, &diag.msg[], - &code[], + &code[..], diag.lvl); }, None => { @@ -165,7 +165,7 @@ fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel { fn create_target_machine(sess: &Session) -> TargetMachineRef { let reloc_model_arg = match sess.opts.cg.relocation_model { - Some(ref s) => &s[], + Some(ref s) => &s[..], None => &sess.target.target.options.relocation_model[] }; let reloc_model = match reloc_model_arg { @@ -198,7 +198,7 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef { let fdata_sections = ffunction_sections; let code_model_arg = match sess.opts.cg.code_model { - Some(ref s) => &s[], + Some(ref s) => &s[..], None => &sess.target.target.options.code_model[] }; @@ -365,7 +365,7 @@ unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef, let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s)) .expect("non-UTF8 SMDiagnostic"); - report_inline_asm(cgcx, &msg[], cookie); + report_inline_asm(cgcx, &msg[..], cookie); } unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) { @@ -711,7 +711,7 @@ pub fn run_passes(sess: &Session, }; let pname = get_cc_prog(sess); - let mut cmd = Command::new(&pname[]); + let mut cmd = Command::new(&pname[..]); cmd.args(&sess.target.target.options.pre_link_args[]); cmd.arg("-nostdlib"); @@ -829,12 +829,12 @@ pub fn run_passes(sess: &Session, for i in 0..trans.modules.len() { if modules_config.emit_obj { let ext = format!("{}.o", i); - remove(sess, &crate_output.with_extension(&ext[])); + remove(sess, &crate_output.with_extension(&ext[..])); } if modules_config.emit_bc && !keep_numbered_bitcode { let ext = format!("{}.bc", i); - remove(sess, &crate_output.with_extension(&ext[])); + remove(sess, &crate_output.with_extension(&ext[..])); } } @@ -960,7 +960,7 @@ fn run_work_multithreaded(sess: &Session, pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { let pname = get_cc_prog(sess); - let mut cmd = Command::new(&pname[]); + let mut cmd = Command::new(&pname[..]); cmd.arg("-c").arg("-o").arg(outputs.path(config::OutputTypeObject)) .arg(outputs.temp_path(config::OutputTypeAssembly)); @@ -975,7 +975,7 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { sess.note(&format!("{:?}", &cmd)[]); let mut note = prog.error.clone(); note.push_all(&prog.output[]); - sess.note(str::from_utf8(¬e[]).unwrap()); + sess.note(str::from_utf8(¬e[..]).unwrap()); sess.abort_if_errors(); } }, diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index cdcd917ee5eb4..8d2a2d51ee423 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -155,7 +155,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { }; self.fmt.sub_mod_ref_str(path.span, *span, - &qualname[], + &qualname[..], self.cur_scope); } } @@ -178,7 +178,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { }; self.fmt.sub_mod_ref_str(path.span, *span, - &qualname[], + &qualname[..], self.cur_scope); } } @@ -197,7 +197,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { let (ref span, ref qualname) = sub_paths[len-2]; self.fmt.sub_type_ref_str(path.span, *span, - &qualname[]); + &qualname[..]); // write the other sub-paths if len <= 2 { @@ -207,7 +207,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { for &(ref span, ref qualname) in sub_paths { self.fmt.sub_mod_ref_str(path.span, *span, - &qualname[], + &qualname[..], self.cur_scope); } } @@ -280,7 +280,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { id, qualname, &path_to_string(p)[], - &typ[]); + &typ[..]); } self.collected_paths.clear(); } @@ -356,7 +356,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { }; let qualname = format!("{}::{}", qualname, &get_ident(method.pe_ident())); - let qualname = &qualname[]; + let qualname = &qualname[..]; // record the decl for this def (if it has one) let decl_id = ty::trait_item_of_item(&self.analysis.ty_cx, @@ -436,9 +436,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { Some(sub_span) => self.fmt.field_str(field.span, Some(sub_span), field.node.id, - &name[], - &qualname[], - &typ[], + &name[..], + &qualname[..], + &typ[..], scope_id), None => self.sess.span_bug(field.span, &format!("Could not find sub-span for field {}", @@ -470,7 +470,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.fmt.typedef_str(full_span, Some(*param_ss), param.id, - &name[], + &name[..], ""); } self.visit_generics(generics); @@ -487,10 +487,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.fmt.fn_str(item.span, sub_span, item.id, - &qualname[], + &qualname[..], self.cur_scope); - self.process_formals(&decl.inputs, &qualname[]); + self.process_formals(&decl.inputs, &qualname[..]); // walk arg and return types for arg in &decl.inputs { @@ -504,7 +504,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { // walk the body self.nest(item.id, |v| v.visit_block(&*body)); - self.process_generic_params(ty_params, item.span, &qualname[], item.id); + self.process_generic_params(ty_params, item.span, &qualname[..], item.id); } fn process_static(&mut self, @@ -526,8 +526,8 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { sub_span, item.id, &get_ident(item.ident), - &qualname[], - &value[], + &qualname[..], + &value[..], &ty_to_string(&*typ)[], self.cur_scope); @@ -549,7 +549,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { sub_span, item.id, &get_ident(item.ident), - &qualname[], + &qualname[..], "", &ty_to_string(&*typ)[], self.cur_scope); @@ -575,17 +575,17 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { sub_span, item.id, ctor_id, - &qualname[], + &qualname[..], self.cur_scope, - &val[]); + &val[..]); // fields for field in &def.fields { - self.process_struct_field_def(field, &qualname[], item.id); + self.process_struct_field_def(field, &qualname[..], item.id); self.visit_ty(&*field.node.ty); } - self.process_generic_params(ty_params, item.span, &qualname[], item.id); + self.process_generic_params(ty_params, item.span, &qualname[..], item.id); } fn process_enum(&mut self, @@ -598,9 +598,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { Some(sub_span) => self.fmt.enum_str(item.span, Some(sub_span), item.id, - &enum_name[], + &enum_name[..], self.cur_scope, - &val[]), + &val[..]), None => self.sess.span_bug(item.span, &format!("Could not find subspan for enum {}", enum_name)[]), @@ -619,9 +619,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.span.span_for_first_ident(variant.span), variant.node.id, name, - &qualname[], - &enum_name[], - &val[], + &qualname[..], + &enum_name[..], + &val[..], item.id); for arg in args { self.visit_ty(&*arg.ty); @@ -637,9 +637,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.span.span_for_first_ident(variant.span), variant.node.id, ctor_id, - &qualname[], - &enum_name[], - &val[], + &qualname[..], + &enum_name[..], + &val[..], item.id); for field in &struct_def.fields { @@ -650,7 +650,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { } } - self.process_generic_params(ty_params, item.span, &enum_name[], item.id); + self.process_generic_params(ty_params, item.span, &enum_name[..], item.id); } fn process_impl(&mut self, @@ -724,9 +724,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.fmt.trait_str(item.span, sub_span, item.id, - &qualname[], + &qualname[..], self.cur_scope, - &val[]); + &val[..]); // super-traits for super_bound in &**trait_refs { @@ -758,7 +758,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { } // walk generics and methods - self.process_generic_params(generics, item.span, &qualname[], item.id); + self.process_generic_params(generics, item.span, &qualname[..], item.id); for method in methods { self.visit_trait_item(method) } @@ -776,9 +776,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.fmt.mod_str(item.span, sub_span, item.id, - &qualname[], + &qualname[..], self.cur_scope, - &filename[]); + &filename[..]); self.nest(item.id, |v| visit::walk_mod(v, m)); } @@ -990,7 +990,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.cur_scope); // walk receiver and args - visit::walk_exprs(self, &args[]); + visit::walk_exprs(self, &args[..]); } fn process_pat(&mut self, p:&ast::Pat) { @@ -1164,7 +1164,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { item.id, cnum, name, - &location[], + &location[..], self.cur_scope); } ast::ItemFn(ref decl, _, _, ref ty_params, ref body) => @@ -1196,8 +1196,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { self.fmt.typedef_str(item.span, sub_span, item.id, - &qualname[], - &value[]); + &qualname[..], + &value[..]); self.visit_ty(&**ty); self.process_generic_params(ty_params, item.span, &qualname, item.id); @@ -1260,7 +1260,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { }; qualname.push_str(&get_ident(method_type.ident)); - let qualname = &qualname[]; + let qualname = &qualname[..]; let sub_span = self.span.sub_span_after_keyword(method_type.span, keywords::Fn); self.fmt.method_decl_str(method_type.span, @@ -1401,7 +1401,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { let mut id = String::from_str("$"); id.push_str(&ex.id.to_string()[]); - self.process_formals(&decl.inputs, &id[]); + self.process_formals(&decl.inputs, &id[..]); // walk arg and return types for arg in &decl.inputs { @@ -1464,7 +1464,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { Some(p.span), id, &path_to_string(p)[], - &value[], + &value[..], "") } def::DefVariant(..) | def::DefTy(..) | def::DefStruct(..) => { @@ -1520,8 +1520,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { sub_span, id, &path_to_string(p)[], - &value[], - &typ[]); + &value[..], + &typ[..]); } self.collected_paths.clear(); @@ -1603,7 +1603,7 @@ pub fn process_crate(sess: &Session, cur_scope: 0 }; - visitor.dump_crate_info(&cratename[], krate); + visitor.dump_crate_info(&cratename[..], krate); visit::walk_crate(&mut visitor, krate); } diff --git a/src/librustc_trans/save/recorder.rs b/src/librustc_trans/save/recorder.rs index 3bd04ed29d4a1..08e36bb1d85bb 100644 --- a/src/librustc_trans/save/recorder.rs +++ b/src/librustc_trans/save/recorder.rs @@ -43,7 +43,7 @@ impl Recorder { assert!(self.dump_spans); let result = format!("span,kind,{},{},text,\"{}\"\n", kind, su.extent_str(span), escape(su.snippet(span))); - self.record(&result[]); + self.record(&result[..]); } } @@ -170,14 +170,14 @@ impl<'a> FmtStrs<'a> { if s.len() > 1020 { &s[..1020] } else { - &s[] + &s[..] } }); let pairs = fields.iter().zip(values); let strs = pairs.map(|(f, v)| format!(",{},\"{}\"", f, escape(String::from_str(v)))); Some(strs.fold(String::new(), |mut s, ss| { - s.push_str(&ss[]); + s.push_str(&ss[..]); s })) } @@ -205,9 +205,9 @@ impl<'a> FmtStrs<'a> { }; let mut result = String::from_str(label); - result.push_str(&values_str[]); + result.push_str(&values_str[..]); result.push_str("\n"); - self.recorder.record(&result[]); + self.recorder.record(&result[..]); } pub fn record_with_span(&mut self, @@ -238,7 +238,7 @@ impl<'a> FmtStrs<'a> { None => return, }; let result = format!("{},{}{}\n", label, self.span.extent_str(sub_span), values_str); - self.recorder.record(&result[]); + self.recorder.record(&result[..]); } pub fn check_and_record(&mut self, diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index b0ed6f9e727a2..2826afb71a2c2 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -566,7 +566,7 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>( param_env: param_env, }; enter_match(bcx, dm, m, col, val, |pats| - check_match::specialize(&mcx, &pats[], &ctor, col, variant_size) + check_match::specialize(&mcx, &pats[..], &ctor, col, variant_size) ) } @@ -987,7 +987,7 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, if has_nested_bindings(m, col) { let expanded = expand_nested_bindings(bcx, m, col, val); compile_submatch_continue(bcx, - &expanded[], + &expanded[..], vals, chk, col, @@ -1233,10 +1233,10 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } let opt_ms = enter_opt(opt_cx, pat_id, dm, m, opt, col, size, val); let mut opt_vals = unpacked; - opt_vals.push_all(&vals_left[]); + opt_vals.push_all(&vals_left[..]); compile_submatch(opt_cx, - &opt_ms[], - &opt_vals[], + &opt_ms[..], + &opt_vals[..], branch_chk.as_ref().unwrap_or(chk), has_genuine_default); } @@ -1255,8 +1255,8 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } _ => { compile_submatch(else_cx, - &defaults[], - &vals_left[], + &defaults[..], + &vals_left[..], chk, has_genuine_default); } @@ -1468,7 +1468,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>, && arm.pats.last().unwrap().node == ast::PatWild(ast::PatWildSingle) }); - compile_submatch(bcx, &matches[], &[discr_datum.val], &chk, has_default); + compile_submatch(bcx, &matches[..], &[discr_datum.val], &chk, has_default); let mut arm_cxs = Vec::new(); for arm_data in &arm_datas { @@ -1482,7 +1482,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>, arm_cxs.push(bcx); } - bcx = scope_cx.fcx.join_blocks(match_id, &arm_cxs[]); + bcx = scope_cx.fcx.join_blocks(match_id, &arm_cxs[..]); return bcx; } diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index ddd720f1e84a8..eaf6eaa2f089d 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -155,7 +155,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Repr<'tcx> { match t.sty { ty::ty_tup(ref elems) => { - Univariant(mk_struct(cx, &elems[], false, t), false) + Univariant(mk_struct(cx, &elems[..], false, t), false) } ty::ty_struct(def_id, substs) => { let fields = ty::lookup_struct_fields(cx.tcx(), def_id); @@ -167,13 +167,13 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let dtor = ty::ty_dtor(cx.tcx(), def_id).has_drop_flag(); if dtor { ftys.push(cx.tcx().types.bool); } - Univariant(mk_struct(cx, &ftys[], packed, t), dtor) + Univariant(mk_struct(cx, &ftys[..], packed, t), dtor) } ty::ty_closure(def_id, _, substs) => { let typer = NormalizingClosureTyper::new(cx.tcx()); let upvars = typer.closure_upvars(def_id, substs).unwrap(); let upvar_types = upvars.iter().map(|u| u.ty).collect::>(); - Univariant(mk_struct(cx, &upvar_types[], false, t), false) + Univariant(mk_struct(cx, &upvar_types[..], false, t), false) } ty::ty_enum(def_id, substs) => { let cases = get_cases(cx.tcx(), def_id, substs); @@ -187,7 +187,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // (Typechecking will reject discriminant-sizing attrs.) assert_eq!(hint, attr::ReprAny); let ftys = if dtor { vec!(cx.tcx().types.bool) } else { vec!() }; - return Univariant(mk_struct(cx, &ftys[], false, t), + return Univariant(mk_struct(cx, &ftys[..], false, t), dtor); } @@ -219,7 +219,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, assert_eq!(hint, attr::ReprAny); let mut ftys = cases[0].tys.clone(); if dtor { ftys.push(cx.tcx().types.bool); } - return Univariant(mk_struct(cx, &ftys[], false, t), + return Univariant(mk_struct(cx, &ftys[..], false, t), dtor); } @@ -320,10 +320,10 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let mut ftys = vec!(ty_of_inttype(cx.tcx(), ity)); ftys.push_all(&c.tys[]); if dtor { ftys.push(cx.tcx().types.bool); } - mk_struct(cx, &ftys[], false, t) + mk_struct(cx, &ftys[..], false, t) }).collect(); - ensure_enum_fits_in_address_space(cx, &fields[], t); + ensure_enum_fits_in_address_space(cx, &fields[..], t); General(ity, fields, dtor) } @@ -453,9 +453,9 @@ fn mk_struct<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, .map(|&ty| type_of::sizing_type_of(cx, ty)).collect() }; - ensure_struct_fits_in_address_space(cx, &lltys[], packed, scapegoat); + ensure_struct_fits_in_address_space(cx, &lltys[..], packed, scapegoat); - let llty_rec = Type::struct_(cx, &lltys[], packed); + let llty_rec = Type::struct_(cx, &lltys[..], packed); Struct { size: machine::llsize_of_alloc(cx, llty_rec), align: machine::llalign_of_min(cx, llty_rec), @@ -659,7 +659,7 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // of the size. // // FIXME #10604: this breaks when vector types are present. - let (size, align) = union_size_and_align(&sts[]); + let (size, align) = union_size_and_align(&sts[..]); let align_s = align as u64; assert_eq!(size % align_s, 0); let align_units = size / align_s - 1; @@ -682,10 +682,10 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, Type::array(&discr_ty, align_s / discr_size - 1), fill_ty]; match name { - None => Type::struct_(cx, &fields[], false), + None => Type::struct_(cx, &fields[..], false), Some(name) => { let mut llty = Type::named_struct(cx, name); - llty.set_struct_body(&fields[], false); + llty.set_struct_body(&fields[..], false); llty } } @@ -763,7 +763,7 @@ pub fn trans_get_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>, fn struct_wrapped_nullable_bitdiscr(bcx: Block, nndiscr: Disr, discrfield: &DiscrField, scrutinee: ValueRef) -> ValueRef { - let llptrptr = GEPi(bcx, scrutinee, &discrfield[]); + let llptrptr = GEPi(bcx, scrutinee, &discrfield[..]); let llptr = Load(bcx, llptrptr); let cmp = if nndiscr == 0 { IntEQ } else { IntNE }; ICmp(bcx, cmp, llptr, C_null(val_ty(llptr)), DebugLoc::None) @@ -851,7 +851,7 @@ pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>, } StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => { if discr != nndiscr { - let llptrptr = GEPi(bcx, val, &discrfield[]); + let llptrptr = GEPi(bcx, val, &discrfield[..]); let llptrty = val_ty(llptrptr).element_type(); Store(bcx, C_null(llptrty), llptrptr) } @@ -933,7 +933,7 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v let val = if needs_cast { let ccx = bcx.ccx(); let fields = st.fields.iter().map(|&ty| type_of::type_of(ccx, ty)).collect::>(); - let real_ty = Type::struct_(ccx, &fields[], st.packed); + let real_ty = Type::struct_(ccx, &fields[..], st.packed); PointerCast(bcx, val, real_ty.ptr_to()) } else { val @@ -972,7 +972,7 @@ pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, let fields = case.fields.iter().map(|&ty| type_of::type_of(bcx.ccx(), ty)).collect::>(); - let real_ty = Type::struct_(ccx, &fields[], case.packed); + let real_ty = Type::struct_(ccx, &fields[..], case.packed); let variant_value = PointerCast(variant_cx, value, real_ty.ptr_to()); variant_cx = f(variant_cx, case, variant_value); @@ -1045,18 +1045,18 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr } General(ity, ref cases, _) => { let case = &cases[discr as uint]; - let (max_sz, _) = union_size_and_align(&cases[]); + let (max_sz, _) = union_size_and_align(&cases[..]); let lldiscr = C_integral(ll_inttype(ccx, ity), discr as u64, true); let mut f = vec![lldiscr]; f.push_all(vals); - let mut contents = build_const_struct(ccx, case, &f[]); + let mut contents = build_const_struct(ccx, case, &f[..]); contents.push_all(&[padding(ccx, max_sz - case.size)]); - C_struct(ccx, &contents[], false) + C_struct(ccx, &contents[..], false) } Univariant(ref st, _dro) => { assert!(discr == 0); let contents = build_const_struct(ccx, st, vals); - C_struct(ccx, &contents[], st.packed) + C_struct(ccx, &contents[..], st.packed) } RawNullablePointer { nndiscr, nnty, .. } => { if discr == nndiscr { @@ -1080,7 +1080,7 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr }).collect::>(); C_struct(ccx, &build_const_struct(ccx, nonnull, - &vals[])[], + &vals[..])[], false) } } diff --git a/src/librustc_trans/trans/asm.rs b/src/librustc_trans/trans/asm.rs index e419be65fc4cc..71cb1d3066c30 100644 --- a/src/librustc_trans/trans/asm.rs +++ b/src/librustc_trans/trans/asm.rs @@ -71,7 +71,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) callee::DontAutorefArg) }) }).collect::>(); - inputs.push_all(&ext_inputs[]); + inputs.push_all(&ext_inputs[..]); // no failure occurred preparing operands, no need to cleanup fcx.pop_custom_cleanup_scope(temp_scope); @@ -91,18 +91,18 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) if !clobbers.is_empty() { clobbers.push(','); } - clobbers.push_str(&more_clobbers[]); + clobbers.push_str(&more_clobbers[..]); } // Add the clobbers to our constraints list if clobbers.len() != 0 && constraints.len() != 0 { constraints.push(','); - constraints.push_str(&clobbers[]); + constraints.push_str(&clobbers[..]); } else { - constraints.push_str(&clobbers[]); + constraints.push_str(&clobbers[..]); } - debug!("Asm Constraints: {}", &constraints[]); + debug!("Asm Constraints: {}", &constraints[..]); let num_outputs = outputs.len(); @@ -112,7 +112,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) } else if num_outputs == 1 { output_types[0] } else { - Type::struct_(bcx.ccx(), &output_types[], false) + Type::struct_(bcx.ccx(), &output_types[..], false) }; let dialect = match ia.dialect { diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 7f7b5cd800660..5cfea3c2677bc 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -247,7 +247,7 @@ fn get_extern_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<'tcx>, let f = decl_rust_fn(ccx, fn_ty, name); let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did); - set_llvm_fn_attrs(ccx, &attrs[], f); + set_llvm_fn_attrs(ccx, &attrs[..], f); ccx.externs().borrow_mut().insert(name.to_string(), f); f @@ -523,7 +523,7 @@ pub fn get_res_dtor<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty::mk_nil(ccx.tcx())); get_extern_fn(ccx, &mut *ccx.externs().borrow_mut(), - &name[], + &name[..], llvm::CCallConv, llty, dtor_ty) @@ -898,14 +898,14 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty::ty_bare_fn(_, ref fn_ty) => { match ccx.sess().target.target.adjust_abi(fn_ty.abi) { Rust | RustCall => { - get_extern_rust_fn(ccx, t, &name[], did) + get_extern_rust_fn(ccx, t, &name[..], did) } RustIntrinsic => { ccx.sess().bug("unexpected intrinsic in trans_external_path") } _ => { foreign::register_foreign_item_fn(ccx, fn_ty.abi, t, - &name[]) + &name[..]) } } } @@ -947,7 +947,7 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let llresult = Invoke(bcx, llfn, - &llargs[], + &llargs[..], normal_bcx.llbb, landing_pad, Some(attributes), @@ -961,7 +961,7 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let llresult = Call(bcx, llfn, - &llargs[], + &llargs[..], Some(attributes), debug_loc); return (llresult, bcx); @@ -1646,7 +1646,7 @@ fn copy_closure_args_to_allocas<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, "argtuple", arg_scope_id)); let untupled_arg_types = match monomorphized_arg_types[0].sty { - ty::ty_tup(ref types) => &types[], + ty::ty_tup(ref types) => &types[..], _ => { bcx.tcx().sess.span_bug(args[0].pat.span, "first arg to `rust-call` ABI function \ @@ -1834,12 +1834,12 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let arg_datums = if abi != RustCall { create_datums_for_fn_args(&fcx, - &monomorphized_arg_types[]) + &monomorphized_arg_types[..]) } else { create_datums_for_fn_args_under_call_abi( bcx, arg_scope, - &monomorphized_arg_types[]) + &monomorphized_arg_types[..]) }; bcx = match closure_env { @@ -1855,7 +1855,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg_scope, &decl.inputs[], arg_datums, - &monomorphized_arg_types[]) + &monomorphized_arg_types[..]) } }; @@ -2000,7 +2000,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, bcx = expr::trans_adt(bcx, result_ty, disr, - &fields[], + &fields[..], None, expr::SaveIn(llresult), debug_loc); @@ -2070,7 +2070,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx ty::erase_late_bound_regions( ccx.tcx(), &ty::ty_fn_args(ctor_ty)); - let arg_datums = create_datums_for_fn_args(&fcx, &arg_tys[]); + let arg_datums = create_datums_for_fn_args(&fcx, &arg_tys[..]); if !type_is_zero_size(fcx.ccx, result_ty.unwrap()) { let dest = fcx.get_ret_slot(bcx, result_ty, "eret_slot"); @@ -2315,7 +2315,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) { ast::ItemImpl(_, _, ref generics, _, _, ref impl_items) => { meth::trans_impl(ccx, item.ident, - &impl_items[], + &impl_items[..], generics, item.id); } @@ -2430,7 +2430,7 @@ fn register_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, _ => panic!("expected bare rust fn") }; - let llfn = decl_rust_fn(ccx, node_type, &sym[]); + let llfn = decl_rust_fn(ccx, node_type, &sym[..]); finish_register_fn(ccx, sp, sym, node_id, llfn); llfn } @@ -2475,7 +2475,7 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty< match fn_sig.inputs[1].sty { ty::ty_tup(ref t_in) => { - inputs.push_all(&t_in[]); + inputs.push_all(&t_in[..]); inputs } _ => ccx.sess().bug("expected tuple'd inputs") @@ -2611,7 +2611,7 @@ pub fn register_fn_llvmty(ccx: &CrateContext, debug!("register_fn_llvmty id={} sym={}", node_id, sym); let llfn = decl_fn(ccx, - &sym[], + &sym[..], cc, llfty, ty::FnConverging(ty::mk_nil(ccx.tcx()))); @@ -2667,7 +2667,7 @@ pub fn create_entry_wrapper(ccx: &CrateContext, let (start_fn, args) = if use_start_lang_item { let start_def_id = match ccx.tcx().lang_items.require(StartFnLangItem) { Ok(id) => id, - Err(s) => { ccx.sess().fatal(&s[]); } + Err(s) => { ccx.sess().fatal(&s[..]); } }; let start_fn = if start_def_id.krate == ast::LOCAL_CRATE { get_item_val(ccx, start_def_id.node) @@ -2783,7 +2783,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { } else { llvm::LLVMTypeOf(v) }; - if contains_null(&sym[]) { + if contains_null(&sym[..]) { ccx.sess().fatal( &format!("Illegal null byte in export_name \ value: `{}`", sym)[]); @@ -2988,7 +2988,7 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec { Some(compressed) => compressed, None => cx.sess().fatal("failed to compress metadata"), }); - let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed[]); + let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed[..]); let llconst = C_struct_in_context(cx.metadata_llcx(), &[llmeta], false); let name = format!("rust_metadata_{}_{}", cx.link_meta().crate_name, diff --git a/src/librustc_trans/trans/builder.rs b/src/librustc_trans/trans/builder.rs index e268c2f0d5cc2..9198fce02002d 100644 --- a/src/librustc_trans/trans/builder.rs +++ b/src/librustc_trans/trans/builder.rs @@ -567,7 +567,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } else { let v = ixs.iter().map(|i| C_i32(self.ccx, *i as i32)).collect::>(); self.count_insn("gepi"); - self.inbounds_gep(base, &v[]) + self.inbounds_gep(base, &v[..]) } } @@ -775,8 +775,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let s = format!("{} ({})", text, self.ccx.sess().codemap().span_to_string(sp)); - debug!("{}", &s[]); - self.add_comment(&s[]); + debug!("{}", &s[..]); + self.add_comment(&s[..]); } } @@ -813,7 +813,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }).collect::>(); debug!("Asm Output Type: {}", self.ccx.tn().type_to_string(output)); - let fty = Type::func(&argtys[], &output); + let fty = Type::func(&argtys[..], &output); unsafe { let v = llvm::LLVMInlineAsm( fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint); diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index bda8b8938b76c..3d3e35cd776f0 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -323,7 +323,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( let llfn = decl_internal_rust_fn(ccx, tuple_fn_ty, - &function_name[]); + &function_name[..]); // let empty_substs = tcx.mk_substs(Substs::trans_empty()); @@ -359,7 +359,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( DebugLoc::None, bare_fn_ty, |bcx, _| Callee { bcx: bcx, data: Fn(llfnpointer) }, - ArgVals(&llargs[]), + ArgVals(&llargs[..]), dest).bcx; finish_fn(&fcx, bcx, sig.output, DebugLoc::None); @@ -792,7 +792,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, // Invoke the actual rust fn and update bcx/llresult. let (llret, b) = base::invoke(bcx, llfn, - &llargs[], + &llargs[..], callee_ty, debug_loc); bcx = b; @@ -833,7 +833,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, callee_ty, llfn, opt_llretslot.unwrap(), - &llargs[], + &llargs[..], arg_tys, debug_loc); } diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index 1c831090e3eaf..85e53618f6da9 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -764,7 +764,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx let name = scope.block_name("clean"); debug!("generating cleanups for {}", name); let bcx_in = self.new_block(label.is_unwind(), - &name[], + &name[..], None); let mut bcx_out = bcx_in; for cleanup in scope.cleanups.iter().rev() { @@ -811,7 +811,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx Some(llbb) => { return llbb; } None => { let name = last_scope.block_name("unwind"); - pad_bcx = self.new_block(true, &name[], None); + pad_bcx = self.new_block(true, &name[..], None); last_scope.cached_landing_pad = Some(pad_bcx.llbb); } } diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index f92df999e6049..c7907ea83c011 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -158,7 +158,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc mangle_internal_name_by_path_and_seq(path, "closure") }); - let llfn = decl_internal_rust_fn(ccx, function_type, &symbol[]); + let llfn = decl_internal_rust_fn(ccx, function_type, &symbol[..]); // set an inline hint for all closures set_inline_hint(llfn); @@ -221,7 +221,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, &[], sig.output, function_type.abi, - ClosureEnv::Closure(&freevars[])); + ClosureEnv::Closure(&freevars[..])); // Don't hoist this to the top of the function. It's perfectly legitimate // to have a zero-size closure (in which case dest will be `Ignore`) and diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index d658003702dca..21f8fb5364409 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -1165,8 +1165,8 @@ pub fn langcall(bcx: Block, Err(s) => { let msg = format!("{} {}", msg, s); match span { - Some(span) => bcx.tcx().sess.span_fatal(span, &msg[]), - None => bcx.tcx().sess.fatal(&msg[]), + Some(span) => bcx.tcx().sess.span_fatal(span, &msg[..]), + None => bcx.tcx().sess.fatal(&msg[..]), } } } diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 86f5589556a78..7705b53ee38c6 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -75,7 +75,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit) ast::LitBool(b) => C_bool(cx, b), ast::LitStr(ref s, _) => C_str_slice(cx, (*s).clone()), ast::LitBinary(ref data) => { - let g = addr_of(cx, C_bytes(cx, &data[]), "binary", e.id); + let g = addr_of(cx, C_bytes(cx, &data[..]), "binary", e.id); let base = ptrcast(g, Type::i8p(cx)); let prev_const = cx.const_unsized().borrow_mut() .insert(base, g); @@ -611,8 +611,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } ast::ExprTup(ref es) => { let repr = adt::represent_type(cx, ety); - let vals = map_list(&es[]); - adt::trans_const(cx, &*repr, 0, &vals[]) + let vals = map_list(&es[..]); + adt::trans_const(cx, &*repr, 0, &vals[..]) } ast::ExprStruct(_, ref fs, ref base_opt) => { let repr = adt::represent_type(cx, ety); @@ -642,9 +642,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } }).collect::>(); if ty::type_is_simd(cx.tcx(), ety) { - C_vector(&cs[]) + C_vector(&cs[..]) } else { - adt::trans_const(cx, &*repr, discr, &cs[]) + adt::trans_const(cx, &*repr, discr, &cs[..]) } }) } @@ -655,9 +655,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, .collect::>(); // If the vector contains enums, an LLVM array won't work. if vs.iter().any(|vi| val_ty(*vi) != llunitty) { - C_struct(cx, &vs[], false) + C_struct(cx, &vs[..], false) } else { - C_array(llunitty, &vs[]) + C_array(llunitty, &vs[..]) } } ast::ExprRepeat(ref elem, ref count) => { @@ -671,9 +671,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let unit_val = const_expr(cx, &**elem, param_substs).0; let vs: Vec<_> = repeat(unit_val).take(n).collect(); if val_ty(unit_val) != llunitty { - C_struct(cx, &vs[], false) + C_struct(cx, &vs[..], false) } else { - C_array(llunitty, &vs[]) + C_array(llunitty, &vs[..]) } } ast::ExprPath(_) | ast::ExprQPath(_) => { @@ -715,14 +715,14 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } ast::ExprCall(ref callee, ref args) => { let opt_def = cx.tcx().def_map.borrow().get(&callee.id).cloned(); - let arg_vals = map_list(&args[]); + let arg_vals = map_list(&args[..]); match opt_def { Some(def::DefStruct(_)) => { if ty::type_is_simd(cx.tcx(), ety) { - C_vector(&arg_vals[]) + C_vector(&arg_vals[..]) } else { let repr = adt::represent_type(cx, ety); - adt::trans_const(cx, &*repr, 0, &arg_vals[]) + adt::trans_const(cx, &*repr, 0, &arg_vals[..]) } } Some(def::DefVariant(enum_did, variant_did, _)) => { @@ -733,7 +733,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, adt::trans_const(cx, &*repr, vinfo.disr_val, - &arg_vals[]) + &arg_vals[..]) } _ => cx.sess().span_bug(e.span, "expected a struct or variant def") } diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs index 96506291b5aae..bfcd757cf2481 100644 --- a/src/librustc_trans/trans/context.rs +++ b/src/librustc_trans/trans/context.rs @@ -288,7 +288,7 @@ impl<'tcx> SharedCrateContext<'tcx> { // such as a function name in the module. // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 let llmod_id = format!("{}.{}.rs", crate_name, i); - let local_ccx = LocalCrateContext::new(&shared_ccx, &llmod_id[]); + let local_ccx = LocalCrateContext::new(&shared_ccx, &llmod_id[..]); shared_ccx.local_ccxs.push(local_ccx); } diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs index e6cd44676cefb..26e12a1af403d 100644 --- a/src/librustc_trans/trans/controlflow.rs +++ b/src/librustc_trans/trans/controlflow.rs @@ -177,7 +177,7 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } let name = format!("then-block-{}-", thn.id); - let then_bcx_in = bcx.fcx.new_id_block(&name[], thn.id); + let then_bcx_in = bcx.fcx.new_id_block(&name[..], thn.id); let then_bcx_out = trans_block(then_bcx_in, &*thn, dest); trans::debuginfo::clear_source_location(bcx.fcx); @@ -378,7 +378,7 @@ pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let did = langcall(bcx, Some(call_info.span), "", PanicFnLangItem); let bcx = callee::trans_lang_call(bcx, did, - &args[], + &args[..], Some(expr::Ignore), call_info.debug_loc()).bcx; Unreachable(bcx); @@ -407,7 +407,7 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let did = langcall(bcx, Some(call_info.span), "", PanicBoundsCheckFnLangItem); let bcx = callee::trans_lang_call(bcx, did, - &args[], + &args[..], Some(expr::Ignore), call_info.debug_loc()).bcx; Unreachable(bcx); diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 23498089c5839..95e598aa21a46 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -299,7 +299,7 @@ impl<'tcx> TypeMap<'tcx> { if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() { let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id); cx.sess().bug(&format!("Type metadata for unique id '{}' is already in the TypeMap!", - &unique_type_id_str[])[]); + &unique_type_id_str[..])[]); } } @@ -380,14 +380,14 @@ impl<'tcx> TypeMap<'tcx> { self.get_unique_type_id_of_type(cx, component_type); let component_type_id = self.get_unique_type_id_as_string(component_type_id); - unique_type_id.push_str(&component_type_id[]); + unique_type_id.push_str(&component_type_id[..]); } }, ty::ty_uniq(inner_type) => { unique_type_id.push('~'); let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type); let inner_type_id = self.get_unique_type_id_as_string(inner_type_id); - unique_type_id.push_str(&inner_type_id[]); + unique_type_id.push_str(&inner_type_id[..]); }, ty::ty_ptr(ty::mt { ty: inner_type, mutbl } ) => { unique_type_id.push('*'); @@ -397,7 +397,7 @@ impl<'tcx> TypeMap<'tcx> { let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type); let inner_type_id = self.get_unique_type_id_as_string(inner_type_id); - unique_type_id.push_str(&inner_type_id[]); + unique_type_id.push_str(&inner_type_id[..]); }, ty::ty_rptr(_, ty::mt { ty: inner_type, mutbl }) => { unique_type_id.push('&'); @@ -407,7 +407,7 @@ impl<'tcx> TypeMap<'tcx> { let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type); let inner_type_id = self.get_unique_type_id_as_string(inner_type_id); - unique_type_id.push_str(&inner_type_id[]); + unique_type_id.push_str(&inner_type_id[..]); }, ty::ty_vec(inner_type, optional_length) => { match optional_length { @@ -421,7 +421,7 @@ impl<'tcx> TypeMap<'tcx> { let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type); let inner_type_id = self.get_unique_type_id_as_string(inner_type_id); - unique_type_id.push_str(&inner_type_id[]); + unique_type_id.push_str(&inner_type_id[..]); }, ty::ty_trait(ref trait_data) => { unique_type_id.push_str("trait "); @@ -452,7 +452,7 @@ impl<'tcx> TypeMap<'tcx> { self.get_unique_type_id_of_type(cx, parameter_type); let parameter_type_id = self.get_unique_type_id_as_string(parameter_type_id); - unique_type_id.push_str(¶meter_type_id[]); + unique_type_id.push_str(¶meter_type_id[..]); unique_type_id.push(','); } @@ -465,7 +465,7 @@ impl<'tcx> TypeMap<'tcx> { ty::FnConverging(ret_ty) => { let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty); let return_type_id = self.get_unique_type_id_as_string(return_type_id); - unique_type_id.push_str(&return_type_id[]); + unique_type_id.push_str(&return_type_id[..]); } ty::FnDiverging => { unique_type_id.push_str("!"); @@ -538,7 +538,7 @@ impl<'tcx> TypeMap<'tcx> { type_map.get_unique_type_id_of_type(cx, type_parameter); let param_type_id = type_map.get_unique_type_id_as_string(param_type_id); - output.push_str(¶m_type_id[]); + output.push_str(¶m_type_id[..]); output.push(','); } @@ -568,7 +568,7 @@ impl<'tcx> TypeMap<'tcx> { self.get_unique_type_id_of_type(cx, parameter_type); let parameter_type_id = self.get_unique_type_id_as_string(parameter_type_id); - unique_type_id.push_str(¶meter_type_id[]); + unique_type_id.push_str(¶meter_type_id[..]); unique_type_id.push(','); } @@ -582,7 +582,7 @@ impl<'tcx> TypeMap<'tcx> { ty::FnConverging(ret_ty) => { let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty); let return_type_id = self.get_unique_type_id_as_string(return_type_id); - unique_type_id.push_str(&return_type_id[]); + unique_type_id.push_str(&return_type_id[..]); } ty::FnDiverging => { unique_type_id.push_str("!"); @@ -806,7 +806,7 @@ pub fn create_global_var_metadata(cx: &CrateContext, let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id)); let var_name = token::get_ident(ident).to_string(); let linkage_name = - namespace_node.mangled_name_of_contained_item(&var_name[]); + namespace_node.mangled_name_of_contained_item(&var_name[..]); let var_scope = namespace_node.scope; let var_name = CString::from_slice(var_name.as_bytes()); @@ -1287,7 +1287,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, match expr.node { ast::ExprClosure(_, ref fn_decl, ref top_level_block) => { let name = format!("fn{}", token::gensym("fn")); - let name = token::str_to_ident(&name[]); + let name = token::str_to_ident(&name[..]); (name, &**fn_decl, // This is not quite right. It should actually inherit // the generics of the enclosing function. @@ -1366,7 +1366,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let (linkage_name, containing_scope) = if has_path { let namespace_node = namespace_for_item(cx, ast_util::local_def(fn_ast_id)); let linkage_name = namespace_node.mangled_name_of_contained_item( - &function_name[]); + &function_name[..]); let containing_scope = namespace_node.scope; (linkage_name, containing_scope) } else { @@ -1451,7 +1451,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, signature.push(type_metadata(cx, arg_type, codemap::DUMMY_SP)); } - return create_DIArray(DIB(cx), &signature[]); + return create_DIArray(DIB(cx), &signature[..]); } fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, @@ -1486,7 +1486,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, actual_self_type, true); - name_to_append_suffix_to.push_str(&actual_self_type_name[]); + name_to_append_suffix_to.push_str(&actual_self_type_name[..]); if generics.is_type_parameterized() { name_to_append_suffix_to.push_str(","); @@ -1525,7 +1525,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let actual_type_name = compute_debuginfo_type_name(cx, actual_type, true); - name_to_append_suffix_to.push_str(&actual_type_name[]); + name_to_append_suffix_to.push_str(&actual_type_name[..]); if index != generics.ty_params.len() - 1 { name_to_append_suffix_to.push_str(","); @@ -1552,7 +1552,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, name_to_append_suffix_to.push('>'); - return create_DIArray(DIB(cx), &template_params[]); + return create_DIArray(DIB(cx), &template_params[..]); } } @@ -1646,7 +1646,7 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let cx: &CrateContext = bcx.ccx(); let filename = span_start(cx, span).file.name.clone(); - let file_metadata = file_metadata(cx, &filename[]); + let file_metadata = file_metadata(cx, &filename[..]); let name = token::get_ident(variable_ident); let loc = span_start(cx, span); @@ -1959,7 +1959,7 @@ impl<'tcx> RecursiveTypeDescription<'tcx> { set_members_of_composite_type(cx, metadata_stub, llvm_type, - &member_descriptions[]); + &member_descriptions[..]); return MetadataCreationResult::new(metadata_stub, true); } } @@ -2031,7 +2031,7 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let struct_metadata_stub = create_struct_stub(cx, struct_llvm_type, - &struct_name[], + &struct_name[..], unique_type_id, containing_scope); @@ -2098,7 +2098,7 @@ fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, unique_type_id, create_struct_stub(cx, tuple_llvm_type, - &tuple_name[], + &tuple_name[..], unique_type_id, UNKNOWN_SCOPE_METADATA), tuple_llvm_type, @@ -2158,7 +2158,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { set_members_of_composite_type(cx, variant_type_metadata, variant_llvm_type, - &member_descriptions[]); + &member_descriptions[..]); MemberDescription { name: "".to_string(), llvm_type: variant_llvm_type, @@ -2191,7 +2191,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { set_members_of_composite_type(cx, variant_type_metadata, variant_llvm_type, - &member_descriptions[]); + &member_descriptions[..]); vec![ MemberDescription { name: "".to_string(), @@ -2291,7 +2291,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { set_members_of_composite_type(cx, variant_type_metadata, variant_llvm_type, - &variant_member_descriptions[]); + &variant_member_descriptions[..]); // Encode the information about the null variant in the union // member's name. @@ -2662,7 +2662,7 @@ fn set_members_of_composite_type(cx: &CrateContext, .collect(); unsafe { - let type_array = create_DIArray(DIB(cx), &member_metadata[]); + let type_array = create_DIArray(DIB(cx), &member_metadata[..]); llvm::LLVMDICompositeTypeSetTypeArray(DIB(cx), composite_type_metadata, type_array); } } @@ -2763,7 +2763,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let member_llvm_types = slice_llvm_type.field_types(); assert!(slice_layout_is_correct(cx, - &member_llvm_types[], + &member_llvm_types[..], element_type)); let member_descriptions = [ MemberDescription { @@ -2789,7 +2789,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let metadata = composite_type_metadata(cx, slice_llvm_type, - &slice_type_name[], + &slice_type_name[..], unique_type_id, &member_descriptions, UNKNOWN_SCOPE_METADATA, @@ -2838,7 +2838,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, llvm::LLVMDIBuilderCreateSubroutineType( DIB(cx), UNKNOWN_FILE_METADATA, - create_DIArray(DIB(cx), &signature_metadata[])) + create_DIArray(DIB(cx), &signature_metadata[..])) }, false); } @@ -2864,7 +2864,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_type); cx.sess().bug(&format!("debuginfo: Unexpected trait-object type in \ trait_pointer_metadata(): {}", - &pp_type_name[])[]); + &pp_type_name[..])[]); } }; @@ -2878,7 +2878,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, composite_type_metadata(cx, trait_llvm_type, - &trait_type_name[], + &trait_type_name[..], unique_type_id, &[], containing_scope, @@ -2998,7 +2998,7 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty::ty_tup(ref elements) => { prepare_tuple_metadata(cx, t, - &elements[], + &elements[..], unique_type_id, usage_site_span).finalize(cx) } @@ -3022,9 +3022,9 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, type id '{}' to already be in \ the debuginfo::TypeMap but it \ was not. (Ty = {})", - &unique_type_id_str[], + &unique_type_id_str[..], ppaux::ty_to_string(cx.tcx(), t)); - cx.sess().span_bug(usage_site_span, &error_message[]); + cx.sess().span_bug(usage_site_span, &error_message[..]); } }; @@ -3037,9 +3037,9 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, UniqueTypeId maps in \ debuginfo::TypeMap. \ UniqueTypeId={}, Ty={}", - &unique_type_id_str[], + &unique_type_id_str[..], ppaux::ty_to_string(cx.tcx(), t)); - cx.sess().span_bug(usage_site_span, &error_message[]); + cx.sess().span_bug(usage_site_span, &error_message[..]); } } None => { @@ -3128,7 +3128,7 @@ fn contains_nodebug_attribute(attributes: &[ast::Attribute]) -> bool { attributes.iter().any(|attr| { let meta_item: &ast::MetaItem = &*attr.node.value; match meta_item.node { - ast::MetaWord(ref value) => &value[] == "no_debug", + ast::MetaWord(ref value) => &value[..] == "no_debug", _ => false } }) diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 480679f43cb76..a31fc3346bd95 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -1046,14 +1046,14 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, controlflow::trans_if(bcx, expr.id, &**cond, &**thn, els.as_ref().map(|e| &**e), dest) } ast::ExprMatch(ref discr, ref arms, _) => { - _match::trans_match(bcx, expr, &**discr, &arms[], dest) + _match::trans_match(bcx, expr, &**discr, &arms[..], dest) } ast::ExprBlock(ref blk) => { controlflow::trans_block(bcx, &**blk, dest) } ast::ExprStruct(_, ref fields, ref base) => { trans_struct(bcx, - &fields[], + &fields[..], base.as_ref().map(|e| &**e), expr.span, expr.id, @@ -1118,7 +1118,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, trans_adt(bcx, expr_ty(bcx, expr), 0, - &numbered_fields[], + &numbered_fields[..], None, dest, expr.debug_loc()) @@ -1153,13 +1153,13 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, trans_overloaded_call(bcx, expr, &**f, - &args[], + &args[..], Some(dest)) } else { callee::trans_call(bcx, expr, &**f, - callee::ArgExprs(&args[]), + callee::ArgExprs(&args[..]), dest) } } @@ -1167,7 +1167,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, callee::trans_method_call(bcx, expr, &*args[0], - callee::ArgExprs(&args[]), + callee::ArgExprs(&args[..]), dest) } ast::ExprBinary(op, ref lhs, ref rhs) => { @@ -1354,11 +1354,11 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>, ty::ty_struct(did, substs) => { let fields = struct_fields(tcx, did, substs); let fields = monomorphize::normalize_associated_type(tcx, &fields); - op(0, &fields[]) + op(0, &fields[..]) } ty::ty_tup(ref v) => { - op(0, &tup_fields(&v[])[]) + op(0, &tup_fields(&v[..])[]) } ty::ty_enum(_, substs) => { @@ -1378,7 +1378,7 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>, tcx, enum_id, variant_id); let fields = struct_fields(tcx, variant_id, substs); let fields = monomorphize::normalize_associated_type(tcx, &fields); - op(variant_info.disr_val, &fields[]) + op(variant_info.disr_val, &fields[..]) } _ => { tcx.sess.bug("resolve didn't map this expr to a \ diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index 8f0e4e647b5b3..10abb90b4bf03 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -238,7 +238,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, _ => ccx.sess().bug("trans_native_call called on non-function type") }; let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig); - let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[]); + let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[..]); let fn_type = cabi::compute_abi_info(ccx, &llsig.llarg_tys[], llsig.llret_ty, @@ -370,7 +370,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let llforeign_retval = CallWithConv(bcx, llfn, - &llargs_foreign[], + &llargs_foreign[..], cc, Some(attrs), call_debug_loc); @@ -611,7 +611,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ccx.tcx().map.path_to_string(id), id, t.repr(tcx)); - let llfn = base::decl_internal_rust_fn(ccx, t, &ps[]); + let llfn = base::decl_internal_rust_fn(ccx, t, &ps[..]); base::set_llvm_fn_attrs(ccx, attrs, llfn); base::trans_fn(ccx, decl, body, llfn, param_substs, id, &[]); llfn @@ -974,7 +974,7 @@ fn lltype_for_fn_from_foreign_types(ccx: &CrateContext, tys: &ForeignTypes) -> T if tys.fn_sig.variadic { Type::variadic_func(&llargument_tys, &llreturn_ty) } else { - Type::func(&llargument_tys[], &llreturn_ty) + Type::func(&llargument_tys[..], &llreturn_ty) } } diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index af90e1ec5c5dd..92040296f4a33 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -170,7 +170,7 @@ pub fn get_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Val let (glue, new_sym) = match ccx.available_drop_glues().borrow().get(&t) { Some(old_sym) => { - let glue = decl_cdecl_fn(ccx, &old_sym[], llfnty, ty::mk_nil(ccx.tcx())); + let glue = decl_cdecl_fn(ccx, &old_sym[..], llfnty, ty::mk_nil(ccx.tcx())); (glue, None) }, None => { @@ -304,7 +304,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, class_did, &[get_drop_glue_type(bcx.ccx(), t)], ty::mk_nil(bcx.tcx())); - let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[], dtor_ty, DebugLoc::None); + let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[..], dtor_ty, DebugLoc::None); variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope); variant_cx @@ -541,7 +541,7 @@ fn declare_generic_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>, ccx, t, &format!("glue_{}", name)[]); - let llfn = decl_cdecl_fn(ccx, &fn_nm[], llfnty, ty::mk_nil(ccx.tcx())); + let llfn = decl_cdecl_fn(ccx, &fn_nm[..], llfnty, ty::mk_nil(ccx.tcx())); note_unique_llvm_symbol(ccx, fn_nm.clone()); return (fn_nm, llfn); } diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 5687247561e9c..a1b66ed94f06b 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -166,7 +166,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let name = token::get_ident(foreign_item.ident); // For `transmute` we can just trans the input expr directly into dest - if &name[] == "transmute" { + if &name[..] == "transmute" { let llret_ty = type_of::type_of(ccx, ret_ty.unwrap()); match args { callee::ArgExprs(arg_exprs) => { @@ -274,13 +274,13 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let call_debug_location = DebugLoc::At(call_info.id, call_info.span); // These are the only intrinsic functions that diverge. - if &name[] == "abort" { + if &name[..] == "abort" { let llfn = ccx.get_intrinsic(&("llvm.trap")); Call(bcx, llfn, &[], None, call_debug_location); fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope); Unreachable(bcx); return Result::new(bcx, C_undef(Type::nil(ccx).ptr_to())); - } else if &name[] == "unreachable" { + } else if &name[..] == "unreachable" { fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope); Unreachable(bcx); return Result::new(bcx, C_nil(ccx)); @@ -307,7 +307,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, }; let simple = get_simple_intrinsic(ccx, &*foreign_item); - let llval = match (simple, &name[]) { + let llval = match (simple, &name[..]) { (Some(llfn), _) => { Call(bcx, llfn, &llargs, None, call_debug_location) } diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 30797344da810..ec48ab0d34a06 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -131,7 +131,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, hash = format!("h{}", state.finish()); ccx.tcx().map.with_path(fn_id.node, |path| { - exported_name(path, &hash[]) + exported_name(path, &hash[..]) }) }; @@ -141,9 +141,9 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let mut hash_id = Some(hash_id); let mut mk_lldecl = |abi: abi::Abi| { let lldecl = if abi != abi::Rust { - foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, &s[]) + foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, &s[..]) } else { - decl_internal_rust_fn(ccx, mono_ty, &s[]) + decl_internal_rust_fn(ccx, mono_ty, &s[..]) }; ccx.monomorphized().borrow_mut().insert(hash_id.take().unwrap(), lldecl); @@ -182,7 +182,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, if abi != abi::Rust { foreign::trans_rust_fn_with_foreign_abi( ccx, &**decl, &**body, &[], d, psubsts, fn_id.node, - Some(&hash[])); + Some(&hash[..])); } else { trans_fn(ccx, &**decl, &**body, d, psubsts, fn_id.node, &[]); } @@ -206,7 +206,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, trans_enum_variant(ccx, parent, &*v, - &args[], + &args[..], this_tv.disr_val, psubsts, d); diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 9d1c0fadefcd2..e4d3699f5c0b8 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -144,7 +144,7 @@ pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let input_tys = inputs.iter().map(|&arg_ty| type_of_explicit_arg(cx, arg_ty)); atys.extend(input_tys); - Type::func(&atys[], &lloutputtype) + Type::func(&atys[..], &lloutputtype) } // Given a function type and a count of ty params, construct an llvm type @@ -332,7 +332,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { let repr = adt::represent_type(cx, t); let tps = substs.types.get_slice(subst::TypeSpace); let name = llvm_type_name(cx, an_enum, did, tps); - adt::incomplete_type_of(cx, &*repr, &name[]) + adt::incomplete_type_of(cx, &*repr, &name[..]) } ty::ty_closure(did, _, ref substs) => { // Only create the named struct, but don't fill it in. We @@ -343,7 +343,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { // contents of the VecPerParamSpace to to construct the llvm // name let name = llvm_type_name(cx, a_closure, did, substs.types.as_slice()); - adt::incomplete_type_of(cx, &*repr, &name[]) + adt::incomplete_type_of(cx, &*repr, &name[..]) } ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) | ty::ty_ptr(ty::mt{ty, ..}) => { @@ -399,7 +399,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { let repr = adt::represent_type(cx, t); let tps = substs.types.get_slice(subst::TypeSpace); let name = llvm_type_name(cx, a_struct, did, tps); - adt::incomplete_type_of(cx, &*repr, &name[]) + adt::incomplete_type_of(cx, &*repr, &name[..]) } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 0183b3474a509..f224d87ae5c61 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1139,14 +1139,14 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty), None) } ast::TyObjectSum(ref ty, ref bounds) => { - match ast_ty_to_trait_ref(this, rscope, &**ty, &bounds[]) { + match ast_ty_to_trait_ref(this, rscope, &**ty, &bounds[..]) { Ok((trait_ref, projection_bounds)) => { trait_ref_to_object_type(this, rscope, ast_ty.span, trait_ref, projection_bounds, - &bounds[]) + &bounds[..]) } Err(ErrorReported) => { this.tcx().types.err @@ -1185,7 +1185,7 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(bare_fn)) } ast::TyPolyTraitRef(ref bounds) => { - conv_ty_poly_trait_ref(this, rscope, ast_ty.span, &bounds[]) + conv_ty_poly_trait_ref(this, rscope, ast_ty.span, &bounds[..]) } ast::TyPath(ref path, id) => { let a_def = match tcx.def_map.borrow().get(&id) { @@ -1424,7 +1424,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>, // Skip the first argument if `self` is present. &self_and_input_tys[1..] } else { - &self_and_input_tys[] + &self_and_input_tys[..] }; let (ior, lfp) = find_implied_output_region(input_tys, input_pats); @@ -1623,7 +1623,7 @@ fn conv_ty_poly_trait_ref<'tcx>( ast_bounds: &[ast::TyParamBound]) -> Ty<'tcx> { - let mut partitioned_bounds = partition_bounds(this.tcx(), span, &ast_bounds[]); + let mut partitioned_bounds = partition_bounds(this.tcx(), span, &ast_bounds[..]); let mut projection_bounds = Vec::new(); let main_trait_bound = if !partitioned_bounds.trait_bounds.is_empty() { diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 81868f3695c28..dfd7816b824c7 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -162,7 +162,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, check_pat_enum(pcx, pat, &path, Some(&[]), expected); } ast::PatEnum(ref path, ref subpats) => { - let subpats = subpats.as_ref().map(|v| &v[]); + let subpats = subpats.as_ref().map(|v| &v[..]); check_pat_enum(pcx, pat, path, subpats, expected); } ast::PatStruct(ref path, ref fields, etc) => { diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 6a9d34d7637b2..84f9e953cc618 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -256,7 +256,7 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, check_argument_types(fcx, call_expr.span, &fn_sig.inputs, - &expected_arg_tys[], + &expected_arg_tys[..], arg_exprs, AutorefArgs::No, fn_sig.variadic, diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 82bd4ae87ffae..978fbbbcffc33 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -901,7 +901,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { debug!("applicable_candidates: {}", applicable_candidates.repr(self.tcx())); if applicable_candidates.len() > 1 { - match self.collapse_candidates_to_trait_pick(&applicable_candidates[]) { + match self.collapse_candidates_to_trait_pick(&applicable_candidates[..]) { Some(pick) => { return Some(Ok(pick)); } None => { } } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 063300a1d7280..0494e1f76865a 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -172,7 +172,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, traits_are = if candidates.len() == 1 {"trait is"} else {"traits are"}, one_of_them = if candidates.len() == 1 {"it"} else {"one of them"}); - fcx.sess().fileline_help(span, &msg[]); + fcx.sess().fileline_help(span, &msg[..]); for (i, trait_did) in candidates.iter().enumerate() { fcx.sess().fileline_help(span, @@ -218,7 +218,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, one_of_them = if candidates.len() == 1 {"it"} else {"one of them"}, name = method_ustring); - fcx.sess().fileline_help(span, &msg[]); + fcx.sess().fileline_help(span, &msg[..]); for (i, trait_info) in candidates.iter().enumerate() { fcx.sess().fileline_help(span, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 30896c1607a88..12553a4c21e56 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2209,7 +2209,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, check_argument_types(fcx, sp, - &err_inputs[], + &err_inputs[..], &[], args_no_rcvr, autoref_args, @@ -2228,7 +2228,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, check_argument_types(fcx, sp, &fty.sig.0.inputs[1..], - &expected_arg_tys[], + &expected_arg_tys[..], args_no_rcvr, autoref_args, fty.sig.0.variadic, @@ -3055,7 +3055,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, ty::ty_struct(base_id, substs) => { debug!("struct named {}", ppaux::ty_to_string(tcx, base_t)); let fields = ty::lookup_struct_fields(tcx, base_id); - fcx.lookup_field_ty(expr.span, base_id, &fields[], + fcx.lookup_field_ty(expr.span, base_id, &fields[..], field.node.name, &(*substs)) } _ => None @@ -3155,7 +3155,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, if tuple_like { debug!("tuple struct named {}", ppaux::ty_to_string(tcx, base_t)); let fields = ty::lookup_struct_fields(tcx, base_id); - fcx.lookup_tup_field_ty(expr.span, base_id, &fields[], + fcx.lookup_tup_field_ty(expr.span, base_id, &fields[..], idx.node, &(*substs)) } else { None @@ -3328,7 +3328,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, class_id, id, fcx.ccx.tcx.mk_substs(struct_substs), - &class_fields[], + &class_fields[..], fields, base_expr.is_none(), None); @@ -3371,7 +3371,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, variant_id, id, fcx.ccx.tcx.mk_substs(substitutions), - &variant_fields[], + &variant_fields[..], fields, true, Some(enum_id)); @@ -3732,10 +3732,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, fcx.write_ty(id, fcx.node_ty(b.id)); } ast::ExprCall(ref callee, ref args) => { - callee::check_call(fcx, expr, &**callee, &args[], expected); + callee::check_call(fcx, expr, &**callee, &args[..], expected); } ast::ExprMethodCall(ident, ref tps, ref args) => { - check_method_call(fcx, expr, ident, &args[], &tps[], expected, lvalue_pref); + check_method_call(fcx, expr, ident, &args[..], &tps[..], expected, lvalue_pref); let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a)); let args_err = arg_tys.fold(false, |rest_err, a| { @@ -3822,7 +3822,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, ast::ExprTup(ref elts) => { let flds = expected.only_has_type(fcx).and_then(|ty| { match ty.sty { - ty::ty_tup(ref flds) => Some(&flds[]), + ty::ty_tup(ref flds) => Some(&flds[..]), _ => None } }); @@ -3856,7 +3856,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let struct_id = match def { Some(def::DefVariant(enum_id, variant_id, true)) => { check_struct_enum_variant(fcx, id, expr.span, enum_id, - variant_id, &fields[]); + variant_id, &fields[..]); enum_id } Some(def::DefTrait(def_id)) => { @@ -3865,7 +3865,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, pprust::path_to_string(path)); check_struct_fields_on_error(fcx, id, - &fields[], + &fields[..], base_expr); def_id }, @@ -3878,7 +3878,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, id, expr.span, struct_did, - &fields[], + &fields[..], base_expr.as_ref().map(|e| &**e)); } _ => { @@ -3887,7 +3887,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, pprust::path_to_string(path)); check_struct_fields_on_error(fcx, id, - &fields[], + &fields[..], base_expr); } } @@ -5232,10 +5232,10 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { } }; (n_tps, inputs, ty::FnConverging(output)) - } else if &name[] == "abort" || &name[] == "unreachable" { + } else if &name[..] == "abort" || &name[..] == "unreachable" { (0, Vec::new(), ty::FnDiverging) } else { - let (n_tps, inputs, output) = match &name[] { + let (n_tps, inputs, output) = match &name[..] { "breakpoint" => (0, Vec::new(), ty::mk_nil(tcx)), "size_of" | "pref_align_of" | "min_align_of" => (1, Vec::new(), ccx.tcx.types.uint), @@ -5260,7 +5260,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { "get_tydesc" => { let tydesc_ty = match ty::get_tydesc_ty(ccx.tcx) { Ok(t) => t, - Err(s) => { span_fatal!(tcx.sess, it.span, E0240, "{}", &s[]); } + Err(s) => { span_fatal!(tcx.sess, it.span, E0240, "{}", &s[..]); } }; let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { ty: tydesc_ty, diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 17c259e674e9f..8be7bc06c5047 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -283,7 +283,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { }; let len = self.region_bound_pairs.len(); - self.relate_free_regions(&fn_sig[], body.id); + self.relate_free_regions(&fn_sig[..], body.id); link_fn_args(self, CodeExtent::from_node_id(body.id), &fn_decl.inputs[]); self.visit_block(body); self.visit_region_obligations(body.id); @@ -674,7 +674,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { } ast::ExprMatch(ref discr, ref arms, _) => { - link_match(rcx, &**discr, &arms[]); + link_match(rcx, &**discr, &arms[..]); visit::walk_expr(rcx, expr); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 44e850a073800..833daf083a732 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -268,7 +268,7 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, ast::TupleVariantKind(ref args) if args.len() > 0 => { let rs = ExplicitRscope; let input_tys: Vec<_> = args.iter().map(|va| ccx.to_ty(&rs, &*va.ty)).collect(); - ty::mk_ctor_fn(tcx, variant_def_id, &input_tys[], enum_scheme.ty) + ty::mk_ctor_fn(tcx, variant_def_id, &input_tys[..], enum_scheme.ty) } ast::TupleVariantKind(_) => { @@ -313,7 +313,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, trait_id, &trait_def.generics, &trait_predicates, - &trait_items[], + &trait_items[..], &m.id, &m.ident.name, &m.explicit_self, @@ -328,7 +328,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, trait_id, &trait_def.generics, &trait_predicates, - &trait_items[], + &trait_items[..], &m.id, &m.pe_ident().name, m.pe_explicit_self(), @@ -871,7 +871,7 @@ fn convert_struct<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, local_def(field.node.id)].ty).collect(); let ctor_fn_ty = ty::mk_ctor_fn(tcx, local_def(ctor_id), - &inputs[], + &inputs[..], selfty); write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty); tcx.tcache.borrow_mut().insert(local_def(ctor_id), @@ -1358,7 +1358,7 @@ fn ty_generics_for_fn_or_method<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, let early_lifetimes = resolve_lifetime::early_bound_lifetimes(generics); ty_generics(ccx, subst::FnSpace, - &early_lifetimes[], + &early_lifetimes[..], &generics.ty_params[], &generics.where_clause, base_generics) diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index d5883d8bf864b..bf29bcd5123f1 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -1065,7 +1065,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { // attribute and report an error with various results if found. if ty::has_attr(tcx, item_def_id, "rustc_variance") { let found = item_variances.repr(tcx); - span_err!(tcx.sess, tcx.map.span(item_id), E0208, "{}", &found[]); + span_err!(tcx.sess, tcx.map.span(item_id), E0208, "{}", &found[..]); } let newly_added = tcx.item_variance_map.borrow_mut() diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 6acd15379461c..44c0acda66fba 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -34,7 +34,7 @@ pub fn highlight(src: &str, class: Option<&str>, id: Option<&str>) -> String { class, id, &mut out).unwrap(); - String::from_utf8_lossy(&out[]).into_owned() + String::from_utf8_lossy(&out[..]).into_owned() } /// Exhausts the `lexer` writing the output into `out`. diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index d79a317185553..c25e2096007ec 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -1120,7 +1120,7 @@ impl Json { /// Returns None otherwise. pub fn as_string<'a>(&'a self) -> Option<&'a str> { match *self { - Json::String(ref s) => Some(&s[]), + Json::String(ref s) => Some(&s[..]), _ => None } } @@ -2237,7 +2237,7 @@ impl ::Decoder for Decoder { return Err(ExpectedError("String or Object".to_string(), format!("{}", json))) } }; - let idx = match names.iter().position(|n| *n == &name[]) { + let idx = match names.iter().position(|n| *n == &name[..]) { Some(idx) => idx, None => return Err(UnknownVariantError(name)) }; @@ -3461,7 +3461,7 @@ mod tests { hm.insert(1, true); let mut mem_buf = Vec::new(); write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap(); - let json_str = from_utf8(&mem_buf[]).unwrap(); + let json_str = from_utf8(&mem_buf[..]).unwrap(); match from_str(json_str) { Err(_) => panic!("Unable to parse json_str: {:?}", json_str), _ => {} // it parsed and we are good to go @@ -3477,7 +3477,7 @@ mod tests { hm.insert(1, true); let mut mem_buf = Vec::new(); write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap(); - let json_str = from_utf8(&mem_buf[]).unwrap(); + let json_str = from_utf8(&mem_buf[..]).unwrap(); match from_str(json_str) { Err(_) => panic!("Unable to parse json_str: {:?}", json_str), _ => {} // it parsed and we are good to go @@ -3517,7 +3517,7 @@ mod tests { write!(&mut writer, "{}", super::as_pretty_json(&json).indent(i)).unwrap(); - let printed = from_utf8(&writer[]).unwrap(); + let printed = from_utf8(&writer[..]).unwrap(); // Check for indents at each line let lines: Vec<&str> = printed.lines().collect(); @@ -3549,7 +3549,7 @@ mod tests { let mut map = HashMap::new(); map.insert(Enum::Foo, 0); let result = json::encode(&map).unwrap(); - assert_eq!(&result[], r#"{"Foo":0}"#); + assert_eq!(&result[..], r#"{"Foo":0}"#); let decoded: HashMap = json::decode(&result).unwrap(); assert_eq!(map, decoded); } diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 517907bcf58e3..70f0ba4bb23af 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -326,7 +326,7 @@ impl Encodable for str { impl Encodable for String { fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_str(&self[]) + s.emit_str(&self[..]) } } diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 1d14b141778f0..88ebe99e981b3 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -103,7 +103,7 @@ impl ops::Deref for OsString { #[inline] fn deref(&self) -> &OsStr { - &self[] + &self[..] } } @@ -267,7 +267,7 @@ impl Debug for OsStr { } impl BorrowFrom for OsStr { - fn borrow_from(owned: &OsString) -> &OsStr { &owned[] } + fn borrow_from(owned: &OsString) -> &OsStr { &owned[..] } } impl ToOwned for OsStr { @@ -288,7 +288,7 @@ impl AsOsStr for OsStr { impl AsOsStr for OsString { fn as_os_str(&self) -> &OsStr { - &self[] + &self[..] } } @@ -300,7 +300,7 @@ impl AsOsStr for str { impl AsOsStr for String { fn as_os_str(&self) -> &OsStr { - OsStr::from_str(&self[]) + OsStr::from_str(&self[..]) } } diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 2fd6631ecc437..e9a8dbb4098af 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -618,14 +618,14 @@ mod tests { #[test] fn read_char_buffered() { let buf = [195u8, 159u8]; - let mut reader = BufReader::with_capacity(1, &buf[]); + let mut reader = BufReader::with_capacity(1, &buf[..]); assert_eq!(reader.chars().next(), Some(Ok('ß'))); } #[test] fn test_chars() { let buf = [195u8, 159u8, b'a']; - let mut reader = BufReader::with_capacity(1, &buf[]); + let mut reader = BufReader::with_capacity(1, &buf[..]); let mut it = reader.chars(); assert_eq!(it.next(), Some(Ok('ß'))); assert_eq!(it.next(), Some(Ok('a'))); diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index 9f3655de20fc2..f6cb4a8c9f369 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -180,7 +180,7 @@ mod tests { fn test_buf_writer() { let mut buf = [0 as u8; 9]; { - let mut writer = Cursor::new(&mut buf[]); + let mut writer = Cursor::new(&mut buf[..]); assert_eq!(writer.position(), 0); assert_eq!(writer.write(&[0]), Ok(1)); assert_eq!(writer.position(), 1); @@ -201,7 +201,7 @@ mod tests { fn test_buf_writer_seek() { let mut buf = [0 as u8; 8]; { - let mut writer = Cursor::new(&mut buf[]); + let mut writer = Cursor::new(&mut buf[..]); assert_eq!(writer.position(), 0); assert_eq!(writer.write(&[1]), Ok(1)); assert_eq!(writer.position(), 1); @@ -229,7 +229,7 @@ mod tests { #[test] fn test_buf_writer_error() { let mut buf = [0 as u8; 2]; - let mut writer = Cursor::new(&mut buf[]); + let mut writer = Cursor::new(&mut buf[..]); assert_eq!(writer.write(&[0]), Ok(1)); assert_eq!(writer.write(&[0, 0]), Ok(1)); assert_eq!(writer.write(&[0, 0]), Ok(0)); @@ -331,7 +331,7 @@ mod tests { #[test] fn seek_past_end() { let buf = [0xff]; - let mut r = Cursor::new(&buf[]); + let mut r = Cursor::new(&buf[..]); assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10)); assert_eq!(r.read(&mut [0]), Ok(0)); @@ -340,7 +340,7 @@ mod tests { assert_eq!(r.read(&mut [0]), Ok(0)); let mut buf = [0]; - let mut r = Cursor::new(&mut buf[]); + let mut r = Cursor::new(&mut buf[..]); assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10)); assert_eq!(r.write(&[3]), Ok(0)); } @@ -348,14 +348,14 @@ mod tests { #[test] fn seek_before_0() { let buf = [0xff_u8]; - let mut r = Cursor::new(&buf[]); + let mut r = Cursor::new(&buf[..]); assert!(r.seek(SeekFrom::End(-2)).is_err()); let mut r = Cursor::new(vec!(10u8)); assert!(r.seek(SeekFrom::End(-2)).is_err()); let mut buf = [0]; - let mut r = Cursor::new(&mut buf[]); + let mut r = Cursor::new(&mut buf[..]); assert!(r.seek(SeekFrom::End(-2)).is_err()); } diff --git a/src/libstd/old_io/buffered.rs b/src/libstd/old_io/buffered.rs index 59a437ad91653..2d2d0d8b33a4c 100644 --- a/src/libstd/old_io/buffered.rs +++ b/src/libstd/old_io/buffered.rs @@ -546,7 +546,7 @@ mod test { assert_eq!(a, &w.get_ref()[]); let w = w.into_inner(); let a: &[_] = &[0, 1]; - assert_eq!(a, &w[]); + assert_eq!(a, &w[..]); } // This is just here to make sure that we don't infinite loop in the @@ -643,14 +643,14 @@ mod test { #[test] fn read_char_buffered() { let buf = [195u8, 159u8]; - let mut reader = BufferedReader::with_capacity(1, &buf[]); + let mut reader = BufferedReader::with_capacity(1, &buf[..]); assert_eq!(reader.read_char(), Ok('ß')); } #[test] fn test_chars() { let buf = [195u8, 159u8, b'a']; - let mut reader = BufferedReader::with_capacity(1, &buf[]); + let mut reader = BufferedReader::with_capacity(1, &buf[..]); let mut it = reader.chars(); assert_eq!(it.next(), Some(Ok('ß'))); assert_eq!(it.next(), Some(Ok('a'))); diff --git a/src/libstd/old_path/mod.rs b/src/libstd/old_path/mod.rs index 37de2993c4d0f..e9005aa22bcfb 100644 --- a/src/libstd/old_path/mod.rs +++ b/src/libstd/old_path/mod.rs @@ -877,7 +877,7 @@ impl BytesContainer for String { } #[inline] fn container_as_str(&self) -> Option<&str> { - Some(&self[]) + Some(&self[..]) } #[inline] fn is_str(_: Option<&String>) -> bool { true } @@ -893,7 +893,7 @@ impl BytesContainer for [u8] { impl BytesContainer for Vec { #[inline] fn container_as_bytes(&self) -> &[u8] { - &self[] + &self[..] } } diff --git a/src/libstd/old_path/windows.rs b/src/libstd/old_path/windows.rs index 07c5e10992b63..3cf15435dd064 100644 --- a/src/libstd/old_path/windows.rs +++ b/src/libstd/old_path/windows.rs @@ -182,7 +182,7 @@ impl GenericPathUnsafe for Path { s.push_str(".."); s.push(SEP); s.push_str(filename); - self.update_normalized(&s[]); + self.update_normalized(&s[..]); } None => { self.update_normalized(filename); @@ -192,20 +192,20 @@ impl GenericPathUnsafe for Path { s.push_str(&self.repr[..end]); s.push(SEP); s.push_str(filename); - self.update_normalized(&s[]); + self.update_normalized(&s[..]); } Some((idxb,idxa,_)) if self.prefix == Some(DiskPrefix) && idxa == self.prefix_len() => { let mut s = String::with_capacity(idxb + filename.len()); s.push_str(&self.repr[..idxb]); s.push_str(filename); - self.update_normalized(&s[]); + self.update_normalized(&s[..]); } Some((idxb,_,_)) => { let mut s = String::with_capacity(idxb + 1 + filename.len()); s.push_str(&self.repr[..idxb]); s.push(SEP); s.push_str(filename); - self.update_normalized(&s[]); + self.update_normalized(&s[..]); } } } @@ -229,7 +229,7 @@ impl GenericPathUnsafe for Path { } fn shares_volume(me: &Path, path: &str) -> bool { // path is assumed to have a prefix of Some(DiskPrefix) - let repr = &me.repr[]; + let repr = &me.repr[..]; match me.prefix { Some(DiskPrefix) => { repr.as_bytes()[0] == path.as_bytes()[0].to_ascii_uppercase() @@ -261,7 +261,7 @@ impl GenericPathUnsafe for Path { else { None }; let pathlen = path_.as_ref().map_or(path.len(), |p| p.len()); let mut s = String::with_capacity(me.repr.len() + 1 + pathlen); - s.push_str(&me.repr[]); + s.push_str(&me.repr[..]); let plen = me.prefix_len(); // if me is "C:" we don't want to add a path separator match me.prefix { @@ -273,9 +273,9 @@ impl GenericPathUnsafe for Path { } match path_ { None => s.push_str(path), - Some(p) => s.push_str(&p[]), + Some(p) => s.push_str(&p[..]), }; - me.update_normalized(&s[]) + me.update_normalized(&s[..]) } if !path.is_empty() { @@ -329,7 +329,7 @@ impl GenericPath for Path { /// Always returns a `Some` value. #[inline] fn as_str<'a>(&'a self) -> Option<&'a str> { - Some(&self.repr[]) + Some(&self.repr[..]) } #[inline] @@ -351,13 +351,13 @@ impl GenericPath for Path { /// Always returns a `Some` value. fn dirname_str<'a>(&'a self) -> Option<&'a str> { Some(match self.sepidx_or_prefix_len() { - None if ".." == self.repr => &self.repr[], + None if ".." == self.repr => &self.repr[..], None => ".", Some((_,idxa,end)) if &self.repr[idxa..end] == ".." => { - &self.repr[] + &self.repr[..] } Some((idxb,_,end)) if &self.repr[idxb..end] == "\\" => { - &self.repr[] + &self.repr[..] } Some((0,idxa,_)) => &self.repr[..idxa], Some((idxb,idxa,_)) => { @@ -379,7 +379,7 @@ impl GenericPath for Path { /// See `GenericPath::filename_str` for info. /// Always returns a `Some` value if `filename` returns a `Some` value. fn filename_str<'a>(&'a self) -> Option<&'a str> { - let repr = &self.repr[]; + let repr = &self.repr[..]; match self.sepidx_or_prefix_len() { None if "." == repr || ".." == repr => None, None => Some(repr), @@ -639,7 +639,7 @@ impl Path { /// Does not distinguish between absolute and cwd-relative paths, e.g. /// C:\foo and C:foo. pub fn str_components<'a>(&'a self) -> StrComponents<'a> { - let repr = &self.repr[]; + let repr = &self.repr[..]; let s = match self.prefix { Some(_) => { let plen = self.prefix_len(); @@ -667,8 +667,8 @@ impl Path { } fn equiv_prefix(&self, other: &Path) -> bool { - let s_repr = &self.repr[]; - let o_repr = &other.repr[]; + let s_repr = &self.repr[..]; + let o_repr = &other.repr[..]; match (self.prefix, other.prefix) { (Some(DiskPrefix), Some(VerbatimDiskPrefix)) => { self.is_absolute() && @@ -823,7 +823,7 @@ impl Path { fn update_sepidx(&mut self) { let s = if self.has_nonsemantic_trailing_slash() { &self.repr[..self.repr.len()-1] - } else { &self.repr[] }; + } else { &self.repr[..] }; let sep_test: fn(char) -> bool = if !prefix_is_verbatim(self.prefix) { is_sep } else { @@ -902,7 +902,7 @@ pub fn is_verbatim(path: &Path) -> bool { /// non-verbatim, the non-verbatim version is returned. /// Otherwise, None is returned. pub fn make_non_verbatim(path: &Path) -> Option { - let repr = &path.repr[]; + let repr = &path.repr[..]; let new_path = match path.prefix { Some(VerbatimPrefix(_)) | Some(DeviceNSPrefix(_)) => return None, Some(UNCPrefix(_,_)) | Some(DiskPrefix) | None => return Some(path.clone()), diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 35221a7e647cc..2e05f6d974e3e 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -37,7 +37,7 @@ pub fn on_panic(obj: &(Any+Send), file: &'static str, line: uint) { let msg = match obj.downcast_ref::<&'static str>() { Some(s) => *s, None => match obj.downcast_ref::() { - Some(s) => &s[], + Some(s) => &s[..], None => "Box", } }; diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 1d992668900f0..3cdf68818ab5e 100755 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -978,7 +978,7 @@ impl ops::Deref for PathBuf { type Target = Path; fn deref(&self) -> &Path { - unsafe { mem::transmute(&self.inner[]) } + unsafe { mem::transmute(&self.inner[..]) } } } @@ -1010,7 +1010,7 @@ impl cmp::Ord for PathBuf { impl AsOsStr for PathBuf { fn as_os_str(&self) -> &OsStr { - &self.inner[] + &self.inner[..] } } diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 4d6d033deee14..a756fb29f81ae 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -265,12 +265,12 @@ fn fill_utf16_buf_base(mut f1: F1, f2: F2) -> Result let mut n = stack_buf.len(); loop { let buf = if n <= stack_buf.len() { - &mut stack_buf[] + &mut stack_buf[..] } else { let extra = n - heap_buf.len(); heap_buf.reserve(extra); heap_buf.set_len(n); - &mut heap_buf[] + &mut heap_buf[..] }; // This function is typically called on windows API functions which diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 502d70d4e1a16..6520d30487c76 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -114,7 +114,7 @@ impl Iterator for Env { let (k, v) = match s.iter().position(|&b| b == '=' as u16) { Some(n) => (&s[..n], &s[n+1..]), - None => (s, &[][]), + None => (s, &[][..]), }; Some((OsStringExt::from_wide(k), OsStringExt::from_wide(v))) } @@ -186,7 +186,7 @@ impl<'a> Iterator for SplitPaths<'a> { if !must_yield && in_progress.is_empty() { None } else { - Some(super::os2path(&in_progress[])) + Some(super::os2path(&in_progress[..])) } } } @@ -208,14 +208,14 @@ pub fn join_paths(paths: I) -> Result return Err(JoinPathsError) } else if v.contains(&sep) { joined.push(b'"' as u16); - joined.push_all(&v[]); + joined.push_all(&v[..]); joined.push(b'"' as u16); } else { - joined.push_all(&v[]); + joined.push_all(&v[..]); } } - Ok(OsStringExt::from_wide(&joined[])) + Ok(OsStringExt::from_wide(&joined[..])) } impl fmt::Display for JoinPathsError { diff --git a/src/libstd/sys/windows/process2.rs b/src/libstd/sys/windows/process2.rs index 19e38196d199f..4e36ed2f17f92 100644 --- a/src/libstd/sys/windows/process2.rs +++ b/src/libstd/sys/windows/process2.rs @@ -472,7 +472,7 @@ mod tests { "echo \"a b c\"" ); assert_eq!( - test_wrapper("\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}", &[]), + test_wrapper("\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}", &[..]), "\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}" ); } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d6778be553e8b..140e21b5d04b7 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -198,7 +198,7 @@ impl Encodable for Ident { impl Decodable for Ident { fn decode(d: &mut D) -> Result { - Ok(str_to_ident(&try!(d.read_str())[])) + Ok(str_to_ident(&try!(d.read_str())[..])) } } diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index 5535e5911e0c2..62291cafbc09e 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -86,7 +86,7 @@ pub fn path_to_string>(path: PI) -> String { if !s.is_empty() { s.push_str("::"); } - s.push_str(&e[]); + s.push_str(&e[..]); s }) } @@ -463,20 +463,20 @@ impl<'ast> Map<'ast> { F: FnOnce(Option<&[Attribute]>) -> T, { let attrs = match self.get(id) { - NodeItem(i) => Some(&i.attrs[]), - NodeForeignItem(fi) => Some(&fi.attrs[]), + NodeItem(i) => Some(&i.attrs[..]), + NodeForeignItem(fi) => Some(&fi.attrs[..]), NodeTraitItem(ref tm) => match **tm { - RequiredMethod(ref type_m) => Some(&type_m.attrs[]), - ProvidedMethod(ref m) => Some(&m.attrs[]), - TypeTraitItem(ref typ) => Some(&typ.attrs[]), + RequiredMethod(ref type_m) => Some(&type_m.attrs[..]), + ProvidedMethod(ref m) => Some(&m.attrs[..]), + TypeTraitItem(ref typ) => Some(&typ.attrs[..]), }, NodeImplItem(ref ii) => { match **ii { - MethodImplItem(ref m) => Some(&m.attrs[]), - TypeImplItem(ref t) => Some(&t.attrs[]), + MethodImplItem(ref m) => Some(&m.attrs[..]), + TypeImplItem(ref t) => Some(&t.attrs[..]), } } - NodeVariant(ref v) => Some(&v.node.attrs[]), + NodeVariant(ref v) => Some(&v.node.attrs[..]), // unit/tuple structs take the attributes straight from // the struct definition. // FIXME(eddyb) make this work again (requires access to the map). @@ -577,7 +577,7 @@ impl<'a, 'ast> NodesMatchingSuffix<'a, 'ast> { None => return false, Some((node_id, name)) => (node_id, name), }; - if &part[] != mod_name.as_str() { + if &part[..] != mod_name.as_str() { return false; } cursor = self.map.get_parent(mod_id); @@ -615,7 +615,7 @@ impl<'a, 'ast> NodesMatchingSuffix<'a, 'ast> { // We are looking at some node `n` with a given name and parent // id; do their names match what I am seeking? fn matches_names(&self, parent_of_n: NodeId, name: Name) -> bool { - name.as_str() == &self.item_name[] && + name.as_str() == &self.item_name[..] && self.suffix_matches(parent_of_n) } } @@ -1026,7 +1026,7 @@ impl<'a> NodePrinter for pprust::State<'a> { fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { let id_str = format!(" (id={})", id); - let id_str = if include_id { &id_str[] } else { "" }; + let id_str = if include_id { &id_str[..] } else { "" }; match map.find(id) { Some(NodeItem(item)) => { diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index b8d4c90f74523..1f0ff2a072859 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -263,11 +263,11 @@ pub fn impl_pretty_name(trait_ref: &Option, ty: &Ty) -> Ident { match *trait_ref { Some(ref trait_ref) => { pretty.push('.'); - pretty.push_str(&pprust::path_to_string(&trait_ref.path)[]); + pretty.push_str(&pprust::path_to_string(&trait_ref.path)); } None => {} } - token::gensym_ident(&pretty[]) + token::gensym_ident(&pretty[..]) } pub fn trait_method_to_ty_method(method: &Method) -> TypeMethod { @@ -679,7 +679,7 @@ pub fn pat_is_ident(pat: P) -> bool { pub fn path_name_eq(a : &ast::Path, b : &ast::Path) -> bool { (a.span == b.span) && (a.global == b.global) - && (segments_name_eq(&a.segments[], &b.segments[])) + && (segments_name_eq(&a.segments[..], &b.segments[..])) } // are two arrays of segments equal when compared unhygienically? diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index a3afe5780d0d5..373f250679a63 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -44,7 +44,7 @@ pub fn is_used(attr: &Attribute) -> bool { pub trait AttrMetaMethods { fn check_name(&self, name: &str) -> bool { - name == &self.name()[] + name == &self.name()[..] } /// Retrieve the name of the meta item, e.g. `foo` in `#[foo]`, @@ -62,7 +62,7 @@ pub trait AttrMetaMethods { impl AttrMetaMethods for Attribute { fn check_name(&self, name: &str) -> bool { - let matches = name == &self.name()[]; + let matches = name == &self.name()[..]; if matches { mark_used(self); } @@ -101,7 +101,7 @@ impl AttrMetaMethods for MetaItem { fn meta_item_list<'a>(&'a self) -> Option<&'a [P]> { match self.node { - MetaList(_, ref l) => Some(&l[]), + MetaList(_, ref l) => Some(&l[..]), _ => None } } @@ -142,7 +142,7 @@ impl AttributeMethods for Attribute { let meta = mk_name_value_item_str( InternedString::new("doc"), token::intern_and_get_ident(&strip_doc_comment_decoration( - &comment)[])); + &comment))); if self.node.style == ast::AttrOuter { f(&mk_attr_outer(self.node.id, meta)) } else { @@ -302,9 +302,9 @@ pub fn find_inline_attr(attrs: &[Attribute]) -> InlineAttr { } MetaList(ref n, ref items) if *n == "inline" => { mark_used(attr); - if contains_name(&items[], "always") { + if contains_name(&items[..], "always") { InlineAlways - } else if contains_name(&items[], "never") { + } else if contains_name(&items[..], "never") { InlineNever } else { InlineHint @@ -326,11 +326,11 @@ pub fn requests_inline(attrs: &[Attribute]) -> bool { /// Tests if a cfg-pattern matches the cfg set pub fn cfg_matches(diagnostic: &SpanHandler, cfgs: &[P], cfg: &ast::MetaItem) -> bool { match cfg.node { - ast::MetaList(ref pred, ref mis) if &pred[] == "any" => + ast::MetaList(ref pred, ref mis) if &pred[..] == "any" => mis.iter().any(|mi| cfg_matches(diagnostic, cfgs, &**mi)), - ast::MetaList(ref pred, ref mis) if &pred[] == "all" => + ast::MetaList(ref pred, ref mis) if &pred[..] == "all" => mis.iter().all(|mi| cfg_matches(diagnostic, cfgs, &**mi)), - ast::MetaList(ref pred, ref mis) if &pred[] == "not" => { + ast::MetaList(ref pred, ref mis) if &pred[..] == "not" => { if mis.len() != 1 { diagnostic.span_err(cfg.span, "expected 1 cfg-pattern"); return false; @@ -382,7 +382,7 @@ fn find_stability_generic<'a, 'outer: for attr in attrs { let tag = attr.name(); - let tag = &tag[]; + let tag = &tag[..]; if tag != "deprecated" && tag != "unstable" && tag != "stable" { continue // not a stability level } @@ -404,7 +404,7 @@ fn find_stability_generic<'a, } } } - if &meta.name()[] == "since" { + if &meta.name()[..] == "since" { match meta.value_str() { Some(v) => since = Some(v), None => { @@ -413,7 +413,7 @@ fn find_stability_generic<'a, } } } - if &meta.name()[] == "reason" { + if &meta.name()[..] == "reason" { match meta.value_str() { Some(v) => reason = Some(v), None => { @@ -501,7 +501,7 @@ pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P]) { if !set.insert(name.clone()) { diagnostic.span_fatal(meta.span, - &format!("duplicate meta item `{}`", name)[]); + &format!("duplicate meta item `{}`", name)); } } } @@ -521,7 +521,7 @@ pub fn find_repr_attrs(diagnostic: &SpanHandler, attr: &Attribute) -> Vec { - let hint = match &word[] { + let hint = match &word[..] { // Can't use "extern" because it's not a lexical identifier. "C" => Some(ReprExtern), "packed" => Some(ReprPacked), diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 3231342cb50c8..099f646294235 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -360,7 +360,7 @@ impl CodeMap { let mut src = if src.starts_with("\u{feff}") { String::from_str(&src[3..]) } else { - String::from_str(&src[]) + String::from_str(&src[..]) }; // Append '\n' in case it's not already there. diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 7ca0591be5064..dfe3477bddc3b 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -311,7 +311,7 @@ impl<'a> fold::Folder for CfgAttrFolder<'a> { } }; - if attr::cfg_matches(self.diag, &self.config[], &cfg) { + if attr::cfg_matches(self.diag, &self.config[..], &cfg) { Some(respan(mi.span, ast::Attribute_ { id: attr::mk_attr_id(), style: attr.node.style, diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 83a4d938bb5d5..fe409f7030f23 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -129,7 +129,7 @@ impl SpanHandler { panic!(ExplicitBug); } pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! { - self.span_bug(sp, &format!("unimplemented {}", msg)[]); + self.span_bug(sp, &format!("unimplemented {}", msg)); } pub fn handler<'a>(&'a self) -> &'a Handler { &self.handler @@ -173,7 +173,7 @@ impl Handler { self.err_count.get()); } } - self.fatal(&s[]); + self.fatal(&s[..]); } pub fn warn(&self, msg: &str) { self.emit.borrow_mut().emit(None, msg, None, Warning); @@ -189,7 +189,7 @@ impl Handler { panic!(ExplicitBug); } pub fn unimpl(&self, msg: &str) -> ! { - self.bug(&format!("unimplemented {}", msg)[]); + self.bug(&format!("unimplemented {}", msg)); } pub fn emit(&self, cmsp: Option<(&codemap::CodeMap, Span)>, @@ -419,12 +419,12 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan, // the span) let span_end = Span { lo: sp.hi, hi: sp.hi, expn_id: sp.expn_id}; let ses = cm.span_to_string(span_end); - try!(print_diagnostic(dst, &ses[], lvl, msg, code)); + try!(print_diagnostic(dst, &ses[..], lvl, msg, code)); if rsp.is_full_span() { try!(custom_highlight_lines(dst, cm, sp, lvl, cm.span_to_lines(sp))); } } else { - try!(print_diagnostic(dst, &ss[], lvl, msg, code)); + try!(print_diagnostic(dst, &ss[..], lvl, msg, code)); if rsp.is_full_span() { try!(highlight_lines(dst, cm, sp, lvl, cm.span_to_lines(sp))); } @@ -436,7 +436,7 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan, Some(code) => match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) { Some(_) => { - try!(print_diagnostic(dst, &ss[], Help, + try!(print_diagnostic(dst, &ss[..], Help, &format!("pass `--explain {}` to see a detailed \ explanation", code)[], None)); } @@ -455,7 +455,7 @@ fn highlight_lines(err: &mut EmitterWriter, let fm = &*lines.file; let mut elided = false; - let mut display_lines = &lines.lines[]; + let mut display_lines = &lines.lines[..]; if display_lines.len() > MAX_LINES { display_lines = &display_lines[0..MAX_LINES]; elided = true; @@ -563,7 +563,7 @@ fn custom_highlight_lines(w: &mut EmitterWriter, -> old_io::IoResult<()> { let fm = &*lines.file; - let lines = &lines.lines[]; + let lines = &lines.lines[..]; if lines.len() > MAX_LINES { if let Some(line) = fm.get_line(lines[0]) { try!(write!(&mut w.dst, "{}:{} {}\n", fm.name, @@ -610,7 +610,7 @@ fn custom_highlight_lines(w: &mut EmitterWriter, s.push('^'); s.push('\n'); print_maybe_styled(w, - &s[], + &s[..], term::attr::ForegroundColor(lvl.color())) } @@ -625,12 +625,12 @@ fn print_macro_backtrace(w: &mut EmitterWriter, codemap::MacroAttribute => ("#[", "]"), codemap::MacroBang => ("", "!") }; - try!(print_diagnostic(w, &ss[], Note, + try!(print_diagnostic(w, &ss[..], Note, &format!("in expansion of {}{}{}", pre, ei.callee.name, post)[], None)); let ss = cm.span_to_string(ei.call_site); - try!(print_diagnostic(w, &ss[], Note, "expansion site", None)); + try!(print_diagnostic(w, &ss[..], Note, "expansion site", None)); Ok(Some(ei.call_site)) } None => Ok(None) @@ -643,6 +643,6 @@ pub fn expect(diag: &SpanHandler, opt: Option, msg: M) -> T where { match opt { Some(t) => t, - None => diag.handler().bug(&msg()[]), + None => diag.handler().bug(&msg()), } } diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 833a6d52acb97..b3afc3fc4dd13 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -59,7 +59,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, Some(previous_span) => { ecx.span_warn(span, &format!( "diagnostic code {} already used", &token::get_ident(code) - )[]); + )); ecx.span_note(previous_span, "previous invocation"); }, None => () @@ -70,7 +70,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, if !diagnostics.contains_key(&code.name) { ecx.span_err(span, &format!( "used diagnostic code {} not registered", &token::get_ident(code) - )[]); + )); } }); MacExpr::new(quote_expr!(ecx, ())) @@ -95,12 +95,12 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, if diagnostics.insert(code.name, description).is_some() { ecx.span_err(span, &format!( "diagnostic code {} already registered", &token::get_ident(*code) - )[]); + )); } }); let sym = Ident::new(token::gensym(&( "__register_diagnostic_".to_string() + &token::get_ident(*code) - )[])); + ))); MacItems::new(vec![quote_item!(ecx, mod $sym {}).unwrap()].into_iter()) } diff --git a/src/libsyntax/ext/concat.rs b/src/libsyntax/ext/concat.rs index 80d128959eaf3..38098e50dee83 100644 --- a/src/libsyntax/ext/concat.rs +++ b/src/libsyntax/ext/concat.rs @@ -62,5 +62,5 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt, } base::MacExpr::new(cx.expr_str( sp, - token::intern_and_get_ident(&accumulator[]))) + token::intern_and_get_ident(&accumulator[..]))) } diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index 63a8bd9ddf1b3..9410a51e7a5f6 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -49,7 +49,7 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree] } } } - let res = str_to_ident(&res_str[]); + let res = str_to_ident(&res_str[..]); let e = P(ast::Expr { id: ast::DUMMY_NODE_ID, diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs index 879718a6399f5..93098484ae013 100644 --- a/src/libsyntax/ext/deriving/bounds.rs +++ b/src/libsyntax/ext/deriving/bounds.rs @@ -24,7 +24,7 @@ pub fn expand_deriving_bound(cx: &mut ExtCtxt, { let name = match mitem.node { MetaWord(ref tname) => { - match &tname[] { + match &tname[..] { "Copy" => "Copy", "Send" | "Sync" => { return cx.span_err(span, diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index f878cb5ca8b78..29e51024d53e4 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -536,15 +536,15 @@ impl<'a> TraitDef<'a> { self, struct_def, type_ident, - &self_args[], - &nonself_args[]) + &self_args[..], + &nonself_args[..]) } else { method_def.expand_struct_method_body(cx, self, struct_def, type_ident, - &self_args[], - &nonself_args[]) + &self_args[..], + &nonself_args[..]) }; method_def.create_method(cx, @@ -576,15 +576,15 @@ impl<'a> TraitDef<'a> { self, enum_def, type_ident, - &self_args[], - &nonself_args[]) + &self_args[..], + &nonself_args[..]) } else { method_def.expand_enum_method_body(cx, self, enum_def, type_ident, self_args, - &nonself_args[]) + &nonself_args[..]) }; method_def.create_method(cx, @@ -934,22 +934,22 @@ impl<'a> MethodDef<'a> { .collect::>(); let self_arg_idents = self_arg_names.iter() - .map(|name|cx.ident_of(&name[])) + .map(|name|cx.ident_of(&name[..])) .collect::>(); // The `vi_idents` will be bound, solely in the catch-all, to // a series of let statements mapping each self_arg to a usize // corresponding to its variant index. let vi_idents: Vec = self_arg_names.iter() - .map(|name| { let vi_suffix = format!("{}_vi", &name[]); - cx.ident_of(&vi_suffix[]) }) + .map(|name| { let vi_suffix = format!("{}_vi", &name[..]); + cx.ident_of(&vi_suffix[..]) }) .collect::>(); // Builds, via callback to call_substructure_method, the // delegated expression that handles the catch-all case, // using `__variants_tuple` to drive logic if necessary. let catch_all_substructure = EnumNonMatchingCollapsed( - self_arg_idents, &variants[], &vi_idents[]); + self_arg_idents, &variants[..], &vi_idents[..]); // These arms are of the form: // (Variant1, Variant1, ...) => Body1 @@ -976,7 +976,7 @@ impl<'a> MethodDef<'a> { idents }; for self_arg_name in self_arg_names.tail() { - let (p, idents) = mk_self_pat(cx, &self_arg_name[]); + let (p, idents) = mk_self_pat(cx, &self_arg_name[..]); subpats.push(p); self_pats_idents.push(idents); } @@ -1032,7 +1032,7 @@ impl<'a> MethodDef<'a> { &**variant, field_tuples); let arm_expr = self.call_substructure_method( - cx, trait_, type_ident, &self_args[], nonself_args, + cx, trait_, type_ident, &self_args[..], nonself_args, &substructure); cx.arm(sp, vec![single_pat], arm_expr) @@ -1085,7 +1085,7 @@ impl<'a> MethodDef<'a> { } let arm_expr = self.call_substructure_method( - cx, trait_, type_ident, &self_args[], nonself_args, + cx, trait_, type_ident, &self_args[..], nonself_args, &catch_all_substructure); // Builds the expression: @@ -1391,7 +1391,7 @@ pub fn cs_fold(use_foldl: bool, } }, EnumNonMatchingCollapsed(ref all_args, _, tuple) => - enum_nonmatch_f(cx, trait_span, (&all_args[], tuple), + enum_nonmatch_f(cx, trait_span, (&all_args[..], tuple), substructure.nonself_args), StaticEnum(..) | StaticStruct(..) => { cx.span_bug(trait_span, "static function in `derive`") @@ -1431,7 +1431,7 @@ pub fn cs_same_method(f: F, f(cx, trait_span, called) }, EnumNonMatchingCollapsed(ref all_self_args, _, tuple) => - enum_nonmatch_f(cx, trait_span, (&all_self_args[], tuple), + enum_nonmatch_f(cx, trait_span, (&all_self_args[..], tuple), substructure.nonself_args), StaticEnum(..) | StaticStruct(..) => { cx.span_bug(trait_span, "static function in `derive`") diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index 0ed9e85e57677..f8bc331bfcfe7 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -102,7 +102,7 @@ pub fn expand_meta_derive(cx: &mut ExtCtxt, |i| push(i))) } - match &tname[] { + match &tname[..] { "Clone" => expand!(clone::expand_deriving_clone), "Hash" => expand!(hash::expand_deriving_hash), diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs index 3f5947672e022..281f23f9e61e8 100644 --- a/src/libsyntax/ext/deriving/show.rs +++ b/src/libsyntax/ext/deriving/show.rs @@ -128,7 +128,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, let formatter = substr.nonself_args[0].clone(); let meth = cx.ident_of("write_fmt"); - let s = token::intern_and_get_ident(&format_string[]); + let s = token::intern_and_get_ident(&format_string[..]); let format_string = cx.expr_str(span, s); // phew, not our responsibility any more! diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs index 5d56707c87a47..9c04d1e928295 100644 --- a/src/libsyntax/ext/env.rs +++ b/src/libsyntax/ext/env.rs @@ -30,7 +30,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT Some(v) => v }; - let e = match env::var(&var[]) { + let e = match env::var(&var[..]) { Err(..) => { cx.expr_path(cx.path_all(sp, true, @@ -56,7 +56,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT cx.ident_of("Some")), vec!(cx.expr_str(sp, token::intern_and_get_ident( - &s[])))) + &s[..])))) } }; MacExpr::new(e) @@ -101,7 +101,7 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } } - let e = match env::var(&var[]) { + let e = match env::var(&var[..]) { Err(_) => { cx.span_err(sp, &msg); cx.expr_usize(sp, 0) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6b7cecee81576..d4dda7390a52f 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -405,7 +405,7 @@ fn expand_mac_invoc(mac: ast::Mac, span: codemap::Span, }, }); let fm = fresh_mark(); - let marked_before = mark_tts(&tts[], fm); + let marked_before = mark_tts(&tts[..], fm); // The span that we pass to the expanders we want to // be the root of the call stack. That's the most @@ -416,7 +416,7 @@ fn expand_mac_invoc(mac: ast::Mac, span: codemap::Span, let opt_parsed = { let expanded = expandfun.expand(fld.cx, mac_span, - &marked_before[]); + &marked_before[..]); parse_thunk(expanded) }; let parsed = match opt_parsed { @@ -425,7 +425,7 @@ fn expand_mac_invoc(mac: ast::Mac, span: codemap::Span, fld.cx.span_err( pth.span, &format!("non-expression macro in expression position: {}", - &extnamestr[] + &extnamestr[..] )[]); return None; } @@ -633,8 +633,8 @@ pub fn expand_item_mac(it: P, } }); // mark before expansion: - let marked_before = mark_tts(&tts[], fm); - expander.expand(fld.cx, it.span, &marked_before[]) + let marked_before = mark_tts(&tts[..], fm); + expander.expand(fld.cx, it.span, &marked_before[..]) } IdentTT(ref expander, span) => { if it.ident.name == parse::token::special_idents::invalid.name { @@ -652,7 +652,7 @@ pub fn expand_item_mac(it: P, } }); // mark before expansion: - let marked_tts = mark_tts(&tts[], fm); + let marked_tts = mark_tts(&tts[..], fm); expander.expand(fld.cx, it.span, it.ident, marked_tts) } MacroRulesTT => { @@ -971,11 +971,11 @@ fn expand_pat(p: P, fld: &mut MacroExpander) -> P { }); let fm = fresh_mark(); - let marked_before = mark_tts(&tts[], fm); + let marked_before = mark_tts(&tts[..], fm); let mac_span = fld.cx.original_span(); let expanded = match expander.expand(fld.cx, mac_span, - &marked_before[]).make_pat() { + &marked_before[..]).make_pat() { Some(e) => e, None => { fld.cx.span_err( @@ -1128,7 +1128,7 @@ fn expand_annotatable(a: Annotatable, if valid_ident { fld.cx.mod_push(it.ident); } - let macro_use = contains_macro_use(fld, &new_attrs[]); + let macro_use = contains_macro_use(fld, &new_attrs[..]); let result = with_exts_frame!(fld.cx.syntax_env, macro_use, noop_fold_item(it, fld)); @@ -1508,7 +1508,7 @@ impl Folder for Marker { node: match node { MacInvocTT(path, tts, ctxt) => { MacInvocTT(self.fold_path(path), - self.fold_tts(&tts[]), + self.fold_tts(&tts[..]), mtwt::apply_mark(self.mark, ctxt)) } }, @@ -1914,7 +1914,7 @@ mod test { .collect(); println!("varref #{}: {:?}, resolves to {}",idx, varref_idents, varref_name); let string = token::get_ident(final_varref_ident); - println!("varref's first segment's string: \"{}\"", &string[]); + println!("varref's first segment's string: \"{}\"", &string[..]); println!("binding #{}: {}, resolves to {}", binding_idx, bindings[binding_idx], binding_name); mtwt::with_sctable(|x| mtwt::display_sctable(x)); @@ -1967,10 +1967,10 @@ foo_module!(); let cxbinds: Vec<&ast::Ident> = bindings.iter().filter(|b| { let ident = token::get_ident(**b); - let string = &ident[]; + let string = &ident[..]; "xx" == string }).collect(); - let cxbinds: &[&ast::Ident] = &cxbinds[]; + let cxbinds: &[&ast::Ident] = &cxbinds[..]; let cxbind = match cxbinds { [b] => b, _ => panic!("expected just one binding for ext_cx") diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 170a455a91326..e17329d7d3300 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -118,7 +118,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } }; let interned_name = token::get_ident(ident); - let name = &interned_name[]; + let name = &interned_name[..]; p.expect(&token::Eq); let e = p.parse_expr(); @@ -218,7 +218,7 @@ impl<'a, 'b> Context<'a, 'b> { let msg = format!("invalid reference to argument `{}` ({})", arg, self.describe_num_args()); - self.ecx.span_err(self.fmtsp, &msg[]); + self.ecx.span_err(self.fmtsp, &msg[..]); return; } { @@ -238,7 +238,7 @@ impl<'a, 'b> Context<'a, 'b> { Some(e) => e.span, None => { let msg = format!("there is no argument named `{}`", name); - self.ecx.span_err(self.fmtsp, &msg[]); + self.ecx.span_err(self.fmtsp, &msg[..]); return; } }; @@ -587,7 +587,7 @@ impl<'a, 'b> Context<'a, 'b> { -> P { let trait_ = match *ty { Known(ref tyname) => { - match &tyname[] { + match &tyname[..] { "" => "Display", "?" => "Debug", "e" => "LowerExp", diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 67990895d071a..2c7bf713aad85 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -668,7 +668,7 @@ fn mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree) -> Vec> { for i in 0..tt.len() { seq.push(tt.get_tt(i)); } - mk_tts(cx, &seq[]) + mk_tts(cx, &seq[..]) } ast::TtToken(sp, ref tok) => { let e_sp = cx.expr_ident(sp, id_ext("_sp")); @@ -757,7 +757,7 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree]) let stmt_let_tt = cx.stmt_let(sp, true, id_ext("tt"), cx.expr_vec_ng(sp)); let mut vector = vec!(stmt_let_sp, stmt_let_tt); - vector.extend(mk_tts(cx, &tts[]).into_iter()); + vector.extend(mk_tts(cx, &tts[..]).into_iter()); let block = cx.expr_block( cx.block_all(sp, vector, diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 7a3a3562bdfdc..2312f6b633dd8 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -65,7 +65,7 @@ pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box { let s = pprust::tts_to_string(tts); base::MacExpr::new(cx.expr_str(sp, - token::intern_and_get_ident(&s[]))) + token::intern_and_get_ident(&s[..]))) } pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) @@ -78,7 +78,7 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) .connect("::"); base::MacExpr::new(cx.expr_str( sp, - token::intern_and_get_ident(&string[]))) + token::intern_and_get_ident(&string[..]))) } /// include! : parse the given file as an expr @@ -151,7 +151,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) // Add this input file to the code map to make it available as // dependency information let filename = format!("{}", file.display()); - let interned = token::intern_and_get_ident(&src[]); + let interned = token::intern_and_get_ident(&src[..]); cx.codemap().new_filemap(filename, src); base::MacExpr::new(cx.expr_str(sp, interned)) diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index d752e34c11253..d5fa791b32b56 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -165,7 +165,7 @@ pub fn count_names(ms: &[TokenTree]) -> usize { pub fn initial_matcher_pos(ms: Rc>, sep: Option, lo: BytePos) -> Box { - let match_idx_hi = count_names(&ms[]); + let match_idx_hi = count_names(&ms[..]); let matches: Vec<_> = (0..match_idx_hi).map(|_| Vec::new()).collect(); box MatcherPos { stack: vec![], @@ -254,13 +254,13 @@ pub fn parse_or_else(sess: &ParseSess, rdr: TtReader, ms: Vec ) -> HashMap> { - match parse(sess, cfg, rdr, &ms[]) { + match parse(sess, cfg, rdr, &ms[..]) { Success(m) => m, Failure(sp, str) => { - sess.span_diagnostic.span_fatal(sp, &str[]) + sess.span_diagnostic.span_fatal(sp, &str[..]) } Error(sp, str) => { - sess.span_diagnostic.span_fatal(sp, &str[]) + sess.span_diagnostic.span_fatal(sp, &str[..]) } } } @@ -447,7 +447,7 @@ pub fn parse(sess: &ParseSess, for dv in &mut (&mut eof_eis[0]).matches { v.push(dv.pop().unwrap()); } - return Success(nameize(sess, ms, &v[])); + return Success(nameize(sess, ms, &v[..])); } else if eof_eis.len() > 1 { return Error(sp, "ambiguity: multiple successful parses".to_string()); } else { @@ -533,7 +533,7 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal { _ => { let token_str = pprust::token_to_string(&p.token); p.fatal(&format!("expected ident, found {}", - &token_str[])[]) + &token_str[..])[]) } }, "path" => { diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index f322cf8bad09c..8d9a9d9d4069e 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -50,7 +50,7 @@ impl<'a> ParserAnyMacro<'a> { following", token_str); let span = parser.span; - parser.span_err(span, &msg[]); + parser.span_err(span, &msg[..]); } } } @@ -192,13 +192,13 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, best_fail_spot = sp; best_fail_msg = (*msg).clone(); }, - Error(sp, ref msg) => cx.span_fatal(sp, &msg[]) + Error(sp, ref msg) => cx.span_fatal(sp, &msg[..]) } } _ => cx.bug("non-matcher found in parsed lhses") } } - cx.span_fatal(best_fail_spot, &best_fail_msg[]); + cx.span_fatal(best_fail_spot, &best_fail_msg[..]); } // Note that macro-by-example's input is also matched against a token tree: diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 83234e3b7a5d8..17016f3ac1179 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -255,7 +255,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { } LisContradiction(ref msg) => { // FIXME #2887 blame macro invoker instead - r.sp_diag.span_fatal(sp.clone(), &msg[]); + r.sp_diag.span_fatal(sp.clone(), &msg[..]); } LisConstraint(len, _) => { if len == 0 { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 3bebba15a572b..a57d675facc3c 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -356,7 +356,7 @@ pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, explain: diag.span_err(span, explain); diag.span_help(span, &format!("add #![feature({})] to the \ crate attributes to enable", - feature)[]); + feature)); } pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain: &str) { @@ -364,7 +364,7 @@ pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain: if diag.handler.can_emit_warnings { diag.span_help(span, &format!("add #![feature({})] to the \ crate attributes to silence this warning", - feature)[]); + feature)); } } @@ -438,7 +438,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { fn visit_item(&mut self, i: &ast::Item) { match i.node { ast::ItemExternCrate(_) => { - if attr::contains_name(&i.attrs[], "macro_reexport") { + if attr::contains_name(&i.attrs[..], "macro_reexport") { self.gate_feature("macro_reexport", i.span, "macros reexports are experimental \ and possibly buggy"); @@ -446,7 +446,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { } ast::ItemForeignMod(ref foreign_module) => { - if attr::contains_name(&i.attrs[], "link_args") { + if attr::contains_name(&i.attrs[..], "link_args") { self.gate_feature("link_args", i.span, "the `link_args` attribute is not portable \ across platforms, it is recommended to \ @@ -460,17 +460,17 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { } ast::ItemFn(..) => { - if attr::contains_name(&i.attrs[], "plugin_registrar") { + if attr::contains_name(&i.attrs[..], "plugin_registrar") { self.gate_feature("plugin_registrar", i.span, "compiler plugins are experimental and possibly buggy"); } - if attr::contains_name(&i.attrs[], "start") { + if attr::contains_name(&i.attrs[..], "start") { self.gate_feature("start", i.span, "a #[start] function is an experimental \ feature whose signature may change \ over time"); } - if attr::contains_name(&i.attrs[], "main") { + if attr::contains_name(&i.attrs[..], "main") { self.gate_feature("main", i.span, "declaration of a nonstandard #[main] \ function may change over time, for now \ @@ -479,7 +479,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { } ast::ItemStruct(..) => { - if attr::contains_name(&i.attrs[], "simd") { + if attr::contains_name(&i.attrs[..], "simd") { self.gate_feature("simd", i.span, "SIMD types are experimental and possibly buggy"); } @@ -505,7 +505,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { removed in the future"); } - if attr::contains_name(&i.attrs[], + if attr::contains_name(&i.attrs[..], "old_orphan_check") { self.gate_feature( "old_orphan_check", @@ -513,7 +513,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { "the new orphan check rules will eventually be strictly enforced"); } - if attr::contains_name(&i.attrs[], + if attr::contains_name(&i.attrs[..], "old_impl_check") { self.gate_feature("old_impl_check", i.span, @@ -528,7 +528,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { } fn visit_foreign_item(&mut self, i: &ast::ForeignItem) { - if attr::contains_name(&i.attrs[], "linkage") { + if attr::contains_name(&i.attrs, "linkage") { self.gate_feature("linkage", i.span, "the `linkage` attribute is experimental \ and not portable across platforms") diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index b17fc7fe82e6c..88f7b33ad241d 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -187,7 +187,7 @@ fn read_line_comments(rdr: &mut StringReader, code_to_the_left: bool, let line = rdr.read_one_line_comment(); debug!("{}", line); // Doc comments are not put in comments. - if is_doc_comment(&line[]) { + if is_doc_comment(&line[..]) { break; } lines.push(line); @@ -224,7 +224,7 @@ fn all_whitespace(s: &str, col: CharPos) -> Option { fn trim_whitespace_prefix_and_push_line(lines: &mut Vec , s: String, col: CharPos) { let len = s.len(); - let s1 = match all_whitespace(&s[], col) { + let s1 = match all_whitespace(&s[..], col) { Some(col) => { if col < len { (&s[col..len]).to_string() @@ -261,7 +261,7 @@ fn read_block_comment(rdr: &mut StringReader, rdr.bump(); rdr.bump(); } - if is_block_doc_comment(&curr_line[]) { + if is_block_doc_comment(&curr_line[..]) { return } assert!(!curr_line.contains_char('\n')); diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 38ba0b38df5a7..cca641a7852f4 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -196,7 +196,7 @@ impl<'a> StringReader<'a> { let mut m = m.to_string(); m.push_str(": "); for c in c.escape_default() { m.push(c) } - self.fatal_span_(from_pos, to_pos, &m[]); + self.fatal_span_(from_pos, to_pos, &m[..]); } /// Report a lexical error spanning [`from_pos`, `to_pos`), appending an @@ -205,7 +205,7 @@ impl<'a> StringReader<'a> { let mut m = m.to_string(); m.push_str(": "); for c in c.escape_default() { m.push(c) } - self.err_span_(from_pos, to_pos, &m[]); + self.err_span_(from_pos, to_pos, &m[..]); } /// Report a lexical error spanning [`from_pos`, `to_pos`), appending the @@ -215,7 +215,7 @@ impl<'a> StringReader<'a> { let from = self.byte_offset(from_pos).to_usize(); let to = self.byte_offset(to_pos).to_usize(); m.push_str(&self.filemap.src[from..to]); - self.fatal_span_(from_pos, to_pos, &m[]); + self.fatal_span_(from_pos, to_pos, &m[..]); } /// Advance peek_tok and peek_span to refer to the next token, and @@ -556,7 +556,7 @@ impl<'a> StringReader<'a> { self.translate_crlf(start_bpos, string, "bare CR not allowed in block doc-comment") } else { string.into_cow() }; - token::DocComment(token::intern(&string[])) + token::DocComment(token::intern(&string[..])) } else { token::Comment }; diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 5f4cf9af5ee75..b5a2b0425c650 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -258,7 +258,7 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option) unreachable!() } }; - match str::from_utf8(&bytes[]).ok() { + match str::from_utf8(&bytes[..]).ok() { Some(s) => { return string_to_filemap(sess, s.to_string(), path.as_str().unwrap().to_string()) @@ -398,7 +398,7 @@ pub fn char_lit(lit: &str) -> (char, isize) { } let msg = format!("lexer should have rejected a bad character escape {}", lit); - let msg2 = &msg[]; + let msg2 = &msg[..]; fn esc(len: usize, lit: &str) -> Option<(char, isize)> { num::from_str_radix(&lit[2..len], 16).ok() @@ -662,7 +662,7 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) -> // s can only be ascii, byte indexing is fine let s2 = s.chars().filter(|&c| c != '_').collect::(); - let mut s = &s2[]; + let mut s = &s2[..]; debug!("integer_lit: {}, {:?}", s, suffix); @@ -817,7 +817,7 @@ mod test { #[test] fn string_to_tts_macro () { let tts = string_to_tts("macro_rules! zip (($a)=>($a))".to_string()); - let tts: &[ast::TokenTree] = &tts[]; + let tts: &[ast::TokenTree] = &tts[..]; match tts { [ast::TtToken(_, token::Ident(name_macro_rules, token::Plain)), ast::TtToken(_, token::Not), @@ -1112,24 +1112,24 @@ mod test { let use_s = "use foo::bar::baz;"; let vitem = string_to_item(use_s.to_string()).unwrap(); let vitem_s = item_to_string(&*vitem); - assert_eq!(&vitem_s[], use_s); + assert_eq!(&vitem_s[..], use_s); let use_s = "use foo::bar as baz;"; let vitem = string_to_item(use_s.to_string()).unwrap(); let vitem_s = item_to_string(&*vitem); - assert_eq!(&vitem_s[], use_s); + assert_eq!(&vitem_s[..], use_s); } #[test] fn parse_extern_crate() { let ex_s = "extern crate foo;"; let vitem = string_to_item(ex_s.to_string()).unwrap(); let vitem_s = item_to_string(&*vitem); - assert_eq!(&vitem_s[], ex_s); + assert_eq!(&vitem_s[..], ex_s); let ex_s = "extern crate \"foo\" as bar;"; let vitem = string_to_item(ex_s.to_string()).unwrap(); let vitem_s = item_to_string(&*vitem); - assert_eq!(&vitem_s[], ex_s); + assert_eq!(&vitem_s[..], ex_s); } fn get_spans_of_pat_idents(src: &str) -> Vec { @@ -1201,19 +1201,19 @@ mod test { let source = "/// doc comment\r\nfn foo() {}".to_string(); let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess).unwrap(); let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap(); - assert_eq!(&doc[], "/// doc comment"); + assert_eq!(&doc[..], "/// doc comment"); let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string(); let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess).unwrap(); let docs = item.attrs.iter().filter(|a| &a.name()[] == "doc") .map(|a| a.value_str().unwrap().to_string()).collect::>(); let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()]; - assert_eq!(&docs[], b); + assert_eq!(&docs[..], b); let source = "/** doc comment\r\n * with CRLF */\r\nfn foo() {}".to_string(); let item = parse_item_from_source_str(name, source, Vec::new(), &sess).unwrap(); let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap(); - assert_eq!(&doc[], "/** doc comment\n * with CRLF */"); + assert_eq!(&doc[..], "/** doc comment\n * with CRLF */"); } #[test] @@ -1233,7 +1233,7 @@ mod test { let span = tts.iter().rev().next().unwrap().get_span(); match sess.span_diagnostic.cm.span_to_snippet(span) { - Ok(s) => assert_eq!(&s[], "{ body }"), + Ok(s) => assert_eq!(&s[..], "{ body }"), Err(_) => panic!("could not get snippet"), } } diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index c6d852627c6ae..8480772ce6c1a 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -41,7 +41,8 @@ pub trait ParserObsoleteMethods { sp: Span, kind: ObsoleteSyntax, kind_str: &str, - desc: &str); + desc: &str, + error: bool); fn is_obsolete_ident(&mut self, ident: &str) -> bool; fn eat_obsolete_ident(&mut self, ident: &str) -> bool; } @@ -68,17 +69,17 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> { ), ObsoleteSyntax::ClosureType => ( "`|usize| -> bool` closure type", - "use unboxed closures instead, no type annotation needed" + "use unboxed closures instead, no type annotation needed", true, ), ObsoleteSyntax::ClosureKind => ( "`:`, `&mut:`, or `&:`", - "rely on inference instead" + "rely on inference instead", true, ), ObsoleteSyntax::Sized => ( "`Sized? T` for removing the `Sized` bound", - "write `T: ?Sized` instead" + "write `T: ?Sized` instead", true, ), ObsoleteSyntax::EmptyIndex => ( diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7d3a7d6010145..6be16bbf6882c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -362,7 +362,7 @@ impl<'a> Parser<'a> { let token_str = Parser::token_to_string(t); let last_span = self.last_span; self.span_fatal(last_span, &format!("unexpected token: `{}`", - token_str)[]); + token_str)); } pub fn unexpected(&mut self) -> ! { @@ -381,7 +381,7 @@ impl<'a> Parser<'a> { let this_token_str = self.this_token_to_string(); self.fatal(&format!("expected `{}`, found `{}`", token_str, - this_token_str)[]) + this_token_str)) } } else { self.expect_one_of(slice::ref_slice(t), &[]); @@ -422,7 +422,7 @@ impl<'a> Parser<'a> { expected.push_all(&*self.expected_tokens); expected.sort_by(|a, b| a.to_string().cmp(&b.to_string())); expected.dedup(); - let expect = tokens_to_string(&expected[]); + let expect = tokens_to_string(&expected[..]); let actual = self.this_token_to_string(); self.fatal( &(if expected.len() > 1 { @@ -436,7 +436,7 @@ impl<'a> Parser<'a> { (format!("expected {}, found `{}`", expect, actual)) - }[]) + })[..] ) } } @@ -469,7 +469,7 @@ impl<'a> Parser<'a> { // might be unit-struct construction; check for recoverableinput error. let mut expected = edible.iter().map(|x| x.clone()).collect::>(); expected.push_all(inedible); - self.check_for_erroneous_unit_struct_expecting(&expected[]); + self.check_for_erroneous_unit_struct_expecting(&expected[..]); } self.expect_one_of(edible, inedible) } @@ -486,9 +486,9 @@ impl<'a> Parser<'a> { .as_ref() .map_or(false, |t| t.is_ident() || t.is_path()) { let mut expected = edible.iter().map(|x| x.clone()).collect::>(); - expected.push_all(&inedible[]); + expected.push_all(&inedible[..]); self.check_for_erroneous_unit_struct_expecting( - &expected[]); + &expected[..]); } self.expect_one_of(edible, inedible) } @@ -511,7 +511,7 @@ impl<'a> Parser<'a> { _ => { let token_str = self.this_token_to_string(); self.fatal(&format!("expected ident, found `{}`", - token_str)[]) + token_str)) } } } @@ -599,7 +599,7 @@ impl<'a> Parser<'a> { let span = self.span; self.span_err(span, &format!("expected identifier, found keyword `{}`", - token_str)[]); + token_str)); } } @@ -608,7 +608,7 @@ impl<'a> Parser<'a> { if self.token.is_reserved_keyword() { let token_str = self.this_token_to_string(); self.fatal(&format!("`{}` is a reserved keyword", - token_str)[]) + token_str)) } } @@ -734,7 +734,7 @@ impl<'a> Parser<'a> { let this_token_str = self.this_token_to_string(); self.fatal(&format!("expected `{}`, found `{}`", gt_str, - this_token_str)[]) + this_token_str)) } } } @@ -1364,7 +1364,7 @@ impl<'a> Parser<'a> { let (inner_attrs, body) = p.parse_inner_attrs_and_block(); let mut attrs = attrs; - attrs.push_all(&inner_attrs[]); + attrs.push_all(&inner_attrs[..]); ProvidedMethod(P(ast::Method { attrs: attrs, id: ast::DUMMY_NODE_ID, @@ -1383,7 +1383,7 @@ impl<'a> Parser<'a> { _ => { let token_str = p.this_token_to_string(); p.fatal(&format!("expected `;` or `{{`, found `{}`", - token_str)[]) + token_str)[..]) } } } @@ -1551,7 +1551,7 @@ impl<'a> Parser<'a> { } else { let this_token_str = self.this_token_to_string(); let msg = format!("expected type, found `{}`", this_token_str); - self.fatal(&msg[]); + self.fatal(&msg[..]); }; let sp = mk_sp(lo, self.last_span.hi); @@ -1699,7 +1699,7 @@ impl<'a> Parser<'a> { token::StrRaw(s, n) => { (true, LitStr( - token::intern_and_get_ident(&parse::raw_str_lit(s.as_str())[]), + token::intern_and_get_ident(&parse::raw_str_lit(s.as_str())), ast::RawStr(n))) } token::Binary(i) => @@ -1944,7 +1944,7 @@ impl<'a> Parser<'a> { }; } _ => { - self.fatal(&format!("expected a lifetime name")[]); + self.fatal(&format!("expected a lifetime name")); } } } @@ -1982,7 +1982,7 @@ impl<'a> Parser<'a> { let msg = format!("expected `,` or `>` after lifetime \ name, found `{}`", this_token_str); - self.fatal(&msg[]); + self.fatal(&msg[..]); } } } @@ -2497,7 +2497,7 @@ impl<'a> Parser<'a> { let last_span = self.last_span; let fstr = n.as_str(); self.span_err(last_span, - &format!("unexpected token: `{}`", n.as_str())[]); + &format!("unexpected token: `{}`", n.as_str())); if fstr.chars().all(|x| "0123456789.".contains_char(x)) { let float = match fstr.parse::().ok() { Some(f) => f, @@ -2506,7 +2506,7 @@ impl<'a> Parser<'a> { self.span_help(last_span, &format!("try parenthesizing the first index; e.g., `(foo.{}){}`", float.trunc() as usize, - &float.fract().to_string()[1..])[]); + &float.fract().to_string()[1..])); } self.abort_if_errors(); @@ -2638,7 +2638,7 @@ impl<'a> Parser<'a> { match self.token { token::SubstNt(name, _) => self.fatal(&format!("unknown macro variable `{}`", - token::get_ident(name))[]), + token::get_ident(name))), _ => {} } } @@ -2700,7 +2700,7 @@ impl<'a> Parser<'a> { }; let token_str = p.this_token_to_string(); p.fatal(&format!("incorrect close delimiter: `{}`", - token_str)[]) + token_str)) }, /* we ought to allow different depths of unquotation */ token::Dollar | token::SubstNt(..) if p.quote_depth > 0 => { @@ -2821,7 +2821,7 @@ impl<'a> Parser<'a> { let this_token_to_string = self.this_token_to_string(); self.span_err(span, &format!("expected expression, found `{}`", - this_token_to_string)[]); + this_token_to_string)); let box_span = mk_sp(lo, self.last_span.hi); self.span_help(box_span, "perhaps you meant `box() (foo)` instead?"); @@ -3274,7 +3274,7 @@ impl<'a> Parser<'a> { if self.token != token::CloseDelim(token::Brace) { let token_str = self.this_token_to_string(); self.fatal(&format!("expected `{}`, found `{}`", "}", - token_str)[]) + token_str)) } etc = true; break; @@ -3575,7 +3575,7 @@ impl<'a> Parser<'a> { let span = self.span; let tok_str = self.this_token_to_string(); self.span_fatal(span, - &format!("expected identifier, found `{}`", tok_str)[]); + &format!("expected identifier, found `{}`", tok_str)); } let ident = self.parse_ident(); let last_span = self.last_span; @@ -3672,7 +3672,7 @@ impl<'a> Parser<'a> { let lo = self.span.lo; if self.check_keyword(keywords::Let) { - check_expected_item(self, &item_attrs[]); + check_expected_item(self, &item_attrs[..]); self.expect_keyword(keywords::Let); let decl = self.parse_let(); P(spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID))) @@ -3681,7 +3681,7 @@ impl<'a> Parser<'a> { && self.look_ahead(1, |t| *t == token::Not) { // it's a macro invocation: - check_expected_item(self, &item_attrs[]); + check_expected_item(self, &item_attrs[..]); // Potential trouble: if we allow macros with paths instead of // idents, we'd need to look ahead past the whole path here... @@ -3709,7 +3709,7 @@ impl<'a> Parser<'a> { let tok_str = self.this_token_to_string(); self.fatal(&format!("expected {}`(` or `{{`, found `{}`", ident_str, - tok_str)[]) + tok_str)) }, }; @@ -3757,7 +3757,7 @@ impl<'a> Parser<'a> { } } else { let found_attrs = !item_attrs.is_empty(); - let item_err = Parser::expected_item_err(&item_attrs[]); + let item_err = Parser::expected_item_err(&item_attrs[..]); match self.parse_item_(item_attrs, false) { Ok(i) => { let hi = i.span.hi; @@ -3794,7 +3794,7 @@ impl<'a> Parser<'a> { let sp = self.span; let tok = self.this_token_to_string(); self.span_fatal_help(sp, - &format!("expected `{{`, found `{}`", tok)[], + &format!("expected `{{`, found `{}`", tok), "place this code inside a block"); } @@ -3829,13 +3829,13 @@ impl<'a> Parser<'a> { while self.token != token::CloseDelim(token::Brace) { // parsing items even when they're not allowed lets us give // better error messages and recover more gracefully. - attributes_box.push_all(&self.parse_outer_attributes()[]); + attributes_box.push_all(&self.parse_outer_attributes()); match self.token { token::Semi => { if !attributes_box.is_empty() { let last_span = self.last_span; self.span_err(last_span, - Parser::expected_item_err(&attributes_box[])); + Parser::expected_item_err(&attributes_box[..])); attributes_box = Vec::new(); } self.bump(); // empty @@ -3927,7 +3927,7 @@ impl<'a> Parser<'a> { if !attributes_box.is_empty() { let last_span = self.last_span; self.span_err(last_span, - Parser::expected_item_err(&attributes_box[])); + Parser::expected_item_err(&attributes_box[..])); } let hi = self.span.hi; @@ -4382,7 +4382,7 @@ impl<'a> Parser<'a> { _ => { let token_str = self.this_token_to_string(); self.fatal(&format!("expected `self`, found `{}`", - token_str)[]) + token_str)) } } } @@ -4711,7 +4711,7 @@ impl<'a> Parser<'a> { let (inner_attrs, body) = self.parse_inner_attrs_and_block(); let body_span = body.span; let mut new_attrs = attrs; - new_attrs.push_all(&inner_attrs[]); + new_attrs.push_all(&inner_attrs[..]); (ast::MethDecl(ident, generics, abi, @@ -5123,7 +5123,7 @@ impl<'a> Parser<'a> { // We parsed attributes for the first item but didn't find it let last_span = self.last_span; self.span_err(last_span, - Parser::expected_item_err(&attrs[])); + Parser::expected_item_err(&attrs[..])); } ast::Mod { @@ -5202,8 +5202,8 @@ impl<'a> Parser<'a> { let mod_name = mod_string.to_string(); let default_path_str = format!("{}.rs", mod_name); let secondary_path_str = format!("{}/mod.rs", mod_name); - let default_path = dir_path.join(&default_path_str[]); - let secondary_path = dir_path.join(&secondary_path_str[]); + let default_path = dir_path.join(&default_path_str[..]); + let secondary_path = dir_path.join(&secondary_path_str[..]); let default_exists = default_path.exists(); let secondary_exists = secondary_path.exists(); @@ -5275,7 +5275,7 @@ impl<'a> Parser<'a> { err.push_str(" -> "); } err.push_str(&path.display().as_cow()[]); - self.span_fatal(id_sp, &err[]); + self.span_fatal(id_sp, &err[..]); } None => () } @@ -5771,7 +5771,7 @@ impl<'a> Parser<'a> { if self.eat_keyword(keywords::Mod) { // MODULE ITEM let (ident, item_, extra_attrs) = - self.parse_item_mod(&attrs[]); + self.parse_item_mod(&attrs[..]); let last_span = self.last_span; let item = self.mk_item(lo, last_span.hi, @@ -6077,7 +6077,7 @@ impl<'a> Parser<'a> { if !attrs.is_empty() { let last_span = self.last_span; self.span_err(last_span, - Parser::expected_item_err(&attrs[])); + Parser::expected_item_err(&attrs[..])); } foreign_items diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 0747a97fa37cc..433c013591c2d 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -482,7 +482,7 @@ macro_rules! declare_special_idents_and_keywords {( $(init_vec.push($si_str);)* $(init_vec.push($sk_str);)* $(init_vec.push($rk_str);)* - interner::StrInterner::prefill(&init_vec[]) + interner::StrInterner::prefill(&init_vec[..]) } }} @@ -644,7 +644,7 @@ impl BytesContainer for InternedString { // of `BytesContainer`, which is itself a workaround for the lack of // DST. unsafe { - let this = &self[]; + let this = &self[..]; mem::transmute::<&[u8],&[u8]>(this.container_as_bytes()) } } diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 707b3c72ecdd7..c72038935d8fb 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -607,7 +607,7 @@ impl Printer { assert_eq!(l, len); // assert!(l <= space); self.space -= len; - self.print_str(&s[]) + self.print_str(&s[..]) } Token::Eof => { // Eof should never get here. diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 4b021f2434f05..9683d44860753 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -602,7 +602,7 @@ impl<'a> State<'a> { pub fn synth_comment(&mut self, text: String) -> IoResult<()> { try!(word(&mut self.s, "/*")); try!(space(&mut self.s)); - try!(word(&mut self.s, &text[])); + try!(word(&mut self.s, &text[..])); try!(space(&mut self.s)); word(&mut self.s, "*/") } @@ -701,7 +701,7 @@ impl<'a> State<'a> { } ast::TyTup(ref elts) => { try!(self.popen()); - try!(self.commasep(Inconsistent, &elts[], + try!(self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&**ty))); if elts.len() == 1 { try!(word(&mut self.s, ",")); @@ -734,10 +734,10 @@ impl<'a> State<'a> { } ast::TyObjectSum(ref ty, ref bounds) => { try!(self.print_type(&**ty)); - try!(self.print_bounds("+", &bounds[])); + try!(self.print_bounds("+", &bounds[..])); } ast::TyPolyTraitRef(ref bounds) => { - try!(self.print_bounds("", &bounds[])); + try!(self.print_bounds("", &bounds[..])); } ast::TyQPath(ref qpath) => { try!(self.print_qpath(&**qpath, false)) @@ -994,7 +994,7 @@ impl<'a> State<'a> { real_bounds.push(b); } } - try!(self.print_bounds(":", &real_bounds[])); + try!(self.print_bounds(":", &real_bounds[..])); try!(self.print_where_clause(generics)); try!(word(&mut self.s, " ")); try!(self.bopen()); @@ -1012,7 +1012,7 @@ impl<'a> State<'a> { try!(self.print_ident(item.ident)); try!(self.cbox(indent_unit)); try!(self.popen()); - try!(self.print_tts(&tts[])); + try!(self.print_tts(&tts[..])); try!(self.pclose()); try!(word(&mut self.s, ";")); try!(self.end()); @@ -1210,7 +1210,7 @@ impl<'a> State<'a> { if !args.is_empty() { try!(self.popen()); try!(self.commasep(Consistent, - &args[], + &args[..], |s, arg| s.print_type(&*arg.ty))); try!(self.pclose()); } @@ -1290,7 +1290,7 @@ impl<'a> State<'a> { try!(word(&mut self.s, "! ")); try!(self.cbox(indent_unit)); try!(self.popen()); - try!(self.print_tts(&tts[])); + try!(self.print_tts(&tts[..])); try!(self.pclose()); try!(word(&mut self.s, ";")); self.end() @@ -1552,7 +1552,7 @@ impl<'a> State<'a> { fn print_expr_vec(&mut self, exprs: &[P]) -> IoResult<()> { try!(self.ibox(indent_unit)); try!(word(&mut self.s, "[")); - try!(self.commasep_exprs(Inconsistent, &exprs[])); + try!(self.commasep_exprs(Inconsistent, &exprs[..])); try!(word(&mut self.s, "]")); self.end() } @@ -1578,7 +1578,7 @@ impl<'a> State<'a> { try!(word(&mut self.s, "{")); try!(self.commasep_cmnt( Consistent, - &fields[], + &fields[..], |s, field| { try!(s.ibox(indent_unit)); try!(s.print_ident(field.ident.node)); @@ -1607,7 +1607,7 @@ impl<'a> State<'a> { fn print_expr_tup(&mut self, exprs: &[P]) -> IoResult<()> { try!(self.popen()); - try!(self.commasep_exprs(Inconsistent, &exprs[])); + try!(self.commasep_exprs(Inconsistent, &exprs[..])); if exprs.len() == 1 { try!(word(&mut self.s, ",")); } @@ -1672,22 +1672,22 @@ impl<'a> State<'a> { try!(self.print_expr_box(place, &**expr)); } ast::ExprVec(ref exprs) => { - try!(self.print_expr_vec(&exprs[])); + try!(self.print_expr_vec(&exprs[..])); } ast::ExprRepeat(ref element, ref count) => { try!(self.print_expr_repeat(&**element, &**count)); } ast::ExprStruct(ref path, ref fields, ref wth) => { - try!(self.print_expr_struct(path, &fields[], wth)); + try!(self.print_expr_struct(path, &fields[..], wth)); } ast::ExprTup(ref exprs) => { - try!(self.print_expr_tup(&exprs[])); + try!(self.print_expr_tup(&exprs[..])); } ast::ExprCall(ref func, ref args) => { - try!(self.print_expr_call(&**func, &args[])); + try!(self.print_expr_call(&**func, &args[..])); } ast::ExprMethodCall(ident, ref tys, ref args) => { - try!(self.print_expr_method_call(ident, &tys[], &args[])); + try!(self.print_expr_method_call(ident, &tys[..], &args[..])); } ast::ExprBinary(op, ref lhs, ref rhs) => { try!(self.print_expr_binary(op, &**lhs, &**rhs)); @@ -1977,7 +1977,7 @@ impl<'a> State<'a> { pub fn print_ident(&mut self, ident: ast::Ident) -> IoResult<()> { if self.encode_idents_with_hygiene { let encoded = ident.encode_with_hygiene(); - try!(word(&mut self.s, &encoded[])) + try!(word(&mut self.s, &encoded[..])) } else { try!(word(&mut self.s, &token::get_ident(ident))) } @@ -2151,7 +2151,7 @@ impl<'a> State<'a> { Some(ref args) => { if !args.is_empty() { try!(self.popen()); - try!(self.commasep(Inconsistent, &args[], + try!(self.commasep(Inconsistent, &args[..], |s, p| s.print_pat(&**p))); try!(self.pclose()); } @@ -2163,7 +2163,7 @@ impl<'a> State<'a> { try!(self.nbsp()); try!(self.word_space("{")); try!(self.commasep_cmnt( - Consistent, &fields[], + Consistent, &fields[..], |s, f| { try!(s.cbox(indent_unit)); if !f.node.is_shorthand { @@ -2184,7 +2184,7 @@ impl<'a> State<'a> { ast::PatTup(ref elts) => { try!(self.popen()); try!(self.commasep(Inconsistent, - &elts[], + &elts[..], |s, p| s.print_pat(&**p))); if elts.len() == 1 { try!(word(&mut self.s, ",")); @@ -2212,7 +2212,7 @@ impl<'a> State<'a> { ast::PatVec(ref before, ref slice, ref after) => { try!(word(&mut self.s, "[")); try!(self.commasep(Inconsistent, - &before[], + &before[..], |s, p| s.print_pat(&**p))); if let Some(ref p) = *slice { if !before.is_empty() { try!(self.word_space(",")); } @@ -2226,7 +2226,7 @@ impl<'a> State<'a> { if !after.is_empty() { try!(self.word_space(",")); } } try!(self.commasep(Inconsistent, - &after[], + &after[..], |s, p| s.print_pat(&**p))); try!(word(&mut self.s, "]")); } @@ -2475,7 +2475,7 @@ impl<'a> State<'a> { ints.push(i); } - try!(self.commasep(Inconsistent, &ints[], |s, &idx| { + try!(self.commasep(Inconsistent, &ints[..], |s, &idx| { if idx < generics.lifetimes.len() { let lifetime = &generics.lifetimes[idx]; s.print_lifetime_def(lifetime) @@ -2562,7 +2562,7 @@ impl<'a> State<'a> { try!(word(&mut self.s, &name)); } ast::MetaNameValue(ref name, ref value) => { - try!(self.word_space(&name[])); + try!(self.word_space(&name[..])); try!(self.word_space("=")); try!(self.print_literal(value)); } @@ -2570,7 +2570,7 @@ impl<'a> State<'a> { try!(word(&mut self.s, &name)); try!(self.popen()); try!(self.commasep(Consistent, - &items[], + &items[..], |s, i| s.print_meta_item(&**i))); try!(self.pclose()); } @@ -2606,7 +2606,7 @@ impl<'a> State<'a> { try!(self.print_path(path, false)); try!(word(&mut self.s, "::{")); } - try!(self.commasep(Inconsistent, &idents[], |s, w| { + try!(self.commasep(Inconsistent, &idents[..], |s, w| { match w.node { ast::PathListIdent { name, .. } => { s.print_ident(name) @@ -2763,13 +2763,13 @@ impl<'a> State<'a> { let mut res = String::from_str("b'"); res.extend(ascii::escape_default(byte).map(|c| c as char)); res.push('\''); - word(&mut self.s, &res[]) + word(&mut self.s, &res[..]) } ast::LitChar(ch) => { let mut res = String::from_str("'"); res.extend(ch.escape_default()); res.push('\''); - word(&mut self.s, &res[]) + word(&mut self.s, &res[..]) } ast::LitInt(i, t) => { match t { @@ -2800,7 +2800,7 @@ impl<'a> State<'a> { &f, &ast_util::float_ty_to_string(t)[])[]) } - ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, &f[]), + ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, &f[..]), ast::LitBool(val) => { if val { word(&mut self.s, "true") } else { word(&mut self.s, "false") } } @@ -2860,7 +2860,7 @@ impl<'a> State<'a> { // Don't print empty lines because they will end up as trailing // whitespace if !line.is_empty() { - try!(word(&mut self.s, &line[])); + try!(word(&mut self.s, &line[..])); } try!(hardbreak(&mut self.s)); } @@ -2875,7 +2875,7 @@ impl<'a> State<'a> { try!(self.ibox(0)); for line in &cmnt.lines { if !line.is_empty() { - try!(word(&mut self.s, &line[])); + try!(word(&mut self.s, &line[..])); } try!(hardbreak(&mut self.s)); } @@ -2908,7 +2908,7 @@ impl<'a> State<'a> { string=st)) } }; - word(&mut self.s, &st[]) + word(&mut self.s, &st[..]) } pub fn next_comment(&mut self) -> Option { diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 98c193c7e6b85..8c2b9edfb22c7 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -54,7 +54,7 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> { // The name to use in `extern crate "name" as std;` let actual_crate_name = match self.alt_std_name { - Some(ref s) => token::intern_and_get_ident(&s[]), + Some(ref s) => token::intern_and_get_ident(&s[..]), None => token::intern_and_get_ident("std"), }; diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 6511dffa6bf8b..31b264eb76d67 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -274,8 +274,8 @@ fn strip_test_functions(krate: ast::Crate) -> ast::Crate { // When not compiling with --test we should not compile the // #[test] functions config::strip_items(krate, |attrs| { - !attr::contains_name(&attrs[], "test") && - !attr::contains_name(&attrs[], "bench") + !attr::contains_name(&attrs[..], "test") && + !attr::contains_name(&attrs[..], "bench") }) } @@ -563,7 +563,7 @@ fn mk_tests(cx: &TestCtxt) -> P { fn is_test_crate(krate: &ast::Crate) -> bool { match attr::find_crate_name(&krate.attrs[]) { - Some(ref s) if "test" == &s[] => true, + Some(ref s) if "test" == &s[..] => true, _ => false } } @@ -603,11 +603,11 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P { // creates $name: $expr let field = |name, expr| ecx.field_imm(span, ecx.ident_of(name), expr); - debug!("encoding {}", ast_util::path_name_i(&path[])); + debug!("encoding {}", ast_util::path_name_i(&path[..])); // path to the #[test] function: "foo::bar::baz" - let path_string = ast_util::path_name_i(&path[]); - let name_expr = ecx.expr_str(span, token::intern_and_get_ident(&path_string[])); + let path_string = ast_util::path_name_i(&path[..]); + let name_expr = ecx.expr_str(span, token::intern_and_get_ident(&path_string[..])); // self::test::StaticTestName($name_expr) let name_expr = ecx.expr_call(span, diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 511442675194e..c286ff9d65c3d 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -110,34 +110,34 @@ impl Eq for RcStr {} impl Ord for RcStr { fn cmp(&self, other: &RcStr) -> Ordering { - self[].cmp(&other[]) + self[..].cmp(&other[..]) } } impl fmt::Debug for RcStr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use std::fmt::Debug; - self[].fmt(f) + self[..].fmt(f) } } impl fmt::Display for RcStr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use std::fmt::Display; - self[].fmt(f) + self[..].fmt(f) } } impl BorrowFrom for str { fn borrow_from(owned: &RcStr) -> &str { - &owned.string[] + &owned.string[..] } } impl Deref for RcStr { type Target = str; - fn deref(&self) -> &str { &self.string[] } + fn deref(&self) -> &str { &self.string[..] } } /// A StrInterner differs from Interner in that it accepts diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs index b978d2d8054e5..be1c623c85905 100644 --- a/src/libterm/terminfo/mod.rs +++ b/src/libterm/terminfo/mod.rs @@ -180,7 +180,7 @@ impl TerminfoTerminal { } }; - let entry = open(&term[]); + let entry = open(&term[..]); if entry.is_err() { if env::var("MSYSCON").ok().map_or(false, |s| { "mintty.exe" == s diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs index fd6e6a843e1f3..c40a5534efbbb 100644 --- a/src/libterm/terminfo/searcher.rs +++ b/src/libterm/terminfo/searcher.rs @@ -60,13 +60,13 @@ pub fn get_dbpath_for_term(term: &str) -> Option> { for p in &dirs_to_search { if p.exists() { let f = first_char.to_string(); - let newp = p.join_many(&[&f[], term]); + let newp = p.join_many(&[&f[..], term]); if newp.exists() { return Some(box newp); } // on some installations the dir is named after the hex of the char (e.g. OS X) let f = format!("{:x}", first_char as uint); - let newp = p.join_many(&[&f[], term]); + let newp = p.join_many(&[&f[..], term]); if newp.exists() { return Some(box newp); } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 2cb30ad9804c6..43b454f2a37fc 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -721,7 +721,7 @@ fn should_sort_failures_before_printing_them() { st.write_failures().unwrap(); let s = match st.out { - Raw(ref m) => String::from_utf8_lossy(&m[]), + Raw(ref m) => String::from_utf8_lossy(&m[..]), Pretty(_) => unreachable!() }; @@ -834,7 +834,7 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec) -> Vec filtered, Some(ref filter) => { filtered.into_iter().filter(|test| { - test.desc.name.as_slice().contains(&filter[]) + test.desc.name.as_slice().contains(&filter[..]) }).collect() } }; diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs index 6f5fc5c1969f0..224f1ef1a8b9b 100644 --- a/src/rustbook/build.rs +++ b/src/rustbook/build.rs @@ -92,7 +92,7 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> { { let urls = markdown_data.replace(".md)", ".html)"); try!(File::create(&preprocessed_path) - .write_str(&urls[])); + .write_str(&urls[..])); } // write the prelude to a temporary HTML file for rustdoc inclusion diff --git a/src/rustbook/error.rs b/src/rustbook/error.rs index 1c10a270acc6c..43c882c7d5b8a 100644 --- a/src/rustbook/error.rs +++ b/src/rustbook/error.rs @@ -52,7 +52,7 @@ impl<'a> Error for &'a str { impl Error for String { fn description<'a>(&'a self) -> &'a str { - &self[] + &self[..] } } @@ -75,7 +75,7 @@ impl Error for IoError { self.desc } fn detail(&self) -> Option<&str> { - self.detail.as_ref().map(|s| &s[]) + self.detail.as_ref().map(|s| &s[..]) } } diff --git a/src/rustbook/test.rs b/src/rustbook/test.rs index d3cb8a7316e86..c5d4875423ae1 100644 --- a/src/rustbook/test.rs +++ b/src/rustbook/test.rs @@ -65,7 +65,7 @@ impl Subcommand for Test { } Err(errors) => { for err in errors { - term.err(&err[]); + term.err(&err[..]); } return Err(box "There was an error." as Box); } diff --git a/src/test/auxiliary/lint_group_plugin_test.rs b/src/test/auxiliary/lint_group_plugin_test.rs index 36b3091852bce..e9d98889ff854 100644 --- a/src/test/auxiliary/lint_group_plugin_test.rs +++ b/src/test/auxiliary/lint_group_plugin_test.rs @@ -37,9 +37,9 @@ impl LintPass for Pass { fn check_item(&mut self, cx: &Context, it: &ast::Item) { let name = token::get_ident(it.ident); - if &name[] == "lintme" { + if &name[..] == "lintme" { cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"); - } else if &name[] == "pleaselintme" { + } else if &name[..] == "pleaselintme" { cx.span_lint(PLEASE_LINT, it.span, "item is named 'pleaselintme'"); } } diff --git a/src/test/auxiliary/lint_plugin_test.rs b/src/test/auxiliary/lint_plugin_test.rs index 9020bb7b0fb2e..ffb234f70c8e7 100644 --- a/src/test/auxiliary/lint_plugin_test.rs +++ b/src/test/auxiliary/lint_plugin_test.rs @@ -35,7 +35,7 @@ impl LintPass for Pass { fn check_item(&mut self, cx: &Context, it: &ast::Item) { let name = token::get_ident(it.ident); - if &name[] == "lintme" { + if &name[..] == "lintme" { cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"); } } diff --git a/src/test/auxiliary/plugin_args.rs b/src/test/auxiliary/plugin_args.rs index 907d80b50db82..d0ab944813a0a 100644 --- a/src/test/auxiliary/plugin_args.rs +++ b/src/test/auxiliary/plugin_args.rs @@ -37,7 +37,7 @@ impl TTMacroExpander for Expander { _: &[ast::TokenTree]) -> Box { let args = self.args.iter().map(|i| pprust::meta_item_to_string(&*i)) .collect::>().connect(", "); - let interned = token::intern_and_get_ident(&args[]); + let interned = token::intern_and_get_ident(&args[..]); MacExpr::new(ecx.expr_str(sp, interned)) } } diff --git a/src/test/run-pass/regions-refcell.rs b/src/test/run-pass/regions-refcell.rs index 019db2a977e4f..20b64ecc0710f 100644 --- a/src/test/run-pass/regions-refcell.rs +++ b/src/test/run-pass/regions-refcell.rs @@ -19,7 +19,7 @@ use std::cell::RefCell; #[cfg(cannot_use_this_yet)] fn foo<'a>(map: RefCell>) { let one = [1u]; - assert_eq!(map.borrow().get("one"), Some(&one[])); + assert_eq!(map.borrow().get("one"), Some(&one[..])); } #[cfg(cannot_use_this_yet_either)] @@ -45,9 +45,9 @@ fn main() { let one = [1u8]; let two = [2u8]; let mut map = HashMap::new(); - map.insert("zero", &zer[]); - map.insert("one", &one[]); - map.insert("two", &two[]); + map.insert("zero", &zer[..]); + map.insert("one", &one[..]); + map.insert("two", &two[..]); let map = RefCell::new(map); foo(map); } From a99e698628cbd396c8100ef776d10ac61d911847 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Wed, 11 Feb 2015 23:16:32 -0800 Subject: [PATCH 68/76] Stabilize std::borrow This commit stabilizes `std::borrow`, making the following modifications to catch up the API with language changes: * It renames `BorrowFrom` to `Borrow`, as was originally intended (but blocked for technical reasons), and reorders the parameters accordingly. * It moves the type parameter of `ToOwned` to an associated type. This is somewhat less flexible, in that each borrowed type must have a unique owned type, but leads to a significant simplification for `Cow`. Flexibility can be regained by using newtyped slices, which is advisable for other reasons anyway. * It removes the owned type parameter from `Cow`, making the type much less verbose. * Deprecates the `is_owned` and `is_borrowed` predicates in favor of direct matching. The above API changes are relatively minor; the basic functionality remains the same, and essentially the whole module is now marked `#[stable]`. [breaking-change] --- src/liballoc/arc.rs | 7 - src/liballoc/rc.rs | 7 - src/libcollections/borrow.rs | 306 +++++++++++++++++ src/libcollections/borrow_stage0.rs | 313 ++++++++++++++++++ src/libcollections/btree/map.rs | 14 +- src/libcollections/btree/node.rs | 9 +- src/libcollections/btree/set.rs | 6 +- src/libcollections/lib.rs | 7 + src/libcollections/slice.rs | 19 +- src/libcollections/str.rs | 13 +- src/libcollections/string.rs | 35 +- src/libcollections/vec.rs | 42 +-- src/libcore/borrow.rs | 265 --------------- src/libcore/hash/mod.rs | 10 - src/libcore/lib.rs | 1 - src/libgraphviz/lib.rs | 6 +- src/librustc/middle/ty.rs | 8 +- src/libstd/collections/hash/map.rs | 26 +- src/libstd/collections/hash/set.rs | 6 +- src/libstd/ffi/os_str.rs | 9 +- src/libstd/lib.rs | 2 +- src/libstd/path.rs | 18 +- src/libsyntax/util/interner.rs | 12 +- .../compile-fail/ufcs-qpath-missing-params.rs | 3 +- src/test/run-make/save-analysis/foo.rs | 2 +- src/test/run-pass/const-polymorphic-paths.rs | 4 +- src/test/run-pass/send_str_hashmap.rs | 2 +- src/test/run-pass/send_str_treemap.rs | 2 +- src/test/run-pass/traits-issue-22019.rs | 6 +- 29 files changed, 753 insertions(+), 407 deletions(-) create mode 100644 src/libcollections/borrow.rs create mode 100644 src/libcollections/borrow_stage0.rs delete mode 100644 src/libcore/borrow.rs diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 3830d7fe29532..a8d6c3ff2b000 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -73,7 +73,6 @@ use core::prelude::*; use core::atomic; use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst}; -use core::borrow::BorrowFrom; use core::fmt; use core::cmp::{Ordering}; use core::default::Default; @@ -244,12 +243,6 @@ impl Clone for Arc { } } -impl BorrowFrom> for T { - fn borrow_from(owned: &Arc) -> &T { - &**owned - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl Deref for Arc { type Target = T; diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index f361c36ec8fa7..3e52886280b8f 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -144,7 +144,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::borrow::BorrowFrom; use core::cell::Cell; use core::clone::Clone; use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering}; @@ -349,12 +348,6 @@ impl Rc { } } -impl BorrowFrom> for T { - fn borrow_from(owned: &Rc) -> &T { - &**owned - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl Deref for Rc { type Target = T; diff --git a/src/libcollections/borrow.rs b/src/libcollections/borrow.rs new file mode 100644 index 0000000000000..62e6f347df398 --- /dev/null +++ b/src/libcollections/borrow.rs @@ -0,0 +1,306 @@ +// Copyright 2014 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. + +//! A module for working with borrowed data. + +#![stable(feature = "rust1", since = "1.0.0")] + +use core::clone::Clone; +use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; +use core::hash::{Hash, Hasher}; +use core::marker::Sized; +use core::ops::Deref; +use core::option::Option; + +use fmt; +use alloc::{rc, arc}; + +use self::Cow::*; + +/// A trait for borrowing data. +/// +/// In general, there may be several ways to "borrow" a piece of data. The +/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T` +/// (a mutable borrow). But types like `Vec` provide additional kinds of +/// borrows: the borrowed slices `&[T]` and `&mut [T]`. +/// +/// When writing generic code, it is often desirable to abstract over all ways +/// of borrowing data from a given type. That is the role of the `Borrow` +/// trait: if `T: Borrow`, then `&U` can be borrowed from `&T`. A given +/// type can be borrowed as multiple different types. In particular, `Vec: +/// Borrow>` and `Vec: Borrow<[T]>`. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Borrow { + /// Immutably borrow from an owned value. + #[stable(feature = "rust1", since = "1.0.0")] + fn borrow(&self) -> &Borrowed; +} + +/// A trait for mutably borrowing data. +/// +/// Similar to `Borrow`, but for mutable borrows. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait BorrowMut : Borrow { + /// Mutably borrow from an owned value. + #[stable(feature = "rust1", since = "1.0.0")] + fn borrow_mut(&mut self) -> &mut Borrowed; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Borrow for T { + fn borrow(&self) -> &T { self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl BorrowMut for T { + fn borrow_mut(&mut self) -> &mut T { self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Borrow for &'a T { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Borrow for &'a mut T { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> BorrowMut for &'a mut T { + fn borrow_mut(&mut self) -> &mut T { &mut **self } +} + +impl Borrow for rc::Rc { + fn borrow(&self) -> &T { &**self } +} + +impl Borrow for arc::Arc { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Borrow for Cow<'a, B> where B: ToOwned, ::Owned: 'a { + fn borrow(&self) -> &B { + &**self + } +} + +/// A generalization of Clone to borrowed data. +/// +/// Some types make it possible to go from borrowed to owned, usually by +/// implementing the `Clone` trait. But `Clone` works only for going from `&T` +/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data +/// from any borrow of a given type. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait ToOwned { + #[stable(feature = "rust1", since = "1.0.0")] + type Owned: Borrow; + + /// Create owned data from borrowed data, usually by copying. + #[stable(feature = "rust1", since = "1.0.0")] + fn to_owned(&self) -> Self::Owned; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ToOwned for T where T: Clone { + type Owned = T; + fn to_owned(&self) -> T { self.clone() } +} + +/// A clone-on-write smart pointer. +/// +/// The type `Cow` is a smart pointer providing clone-on-write functionality: it +/// can enclose and provide immutable access to borrowed data, and clone the +/// data lazily when mutation or ownership is required. The type is designed to +/// work with general borrowed data via the `Borrow` trait. +/// +/// `Cow` implements both `Deref`, which means that you can call +/// non-mutating methods directly on the data it encloses. If mutation +/// is desired, `to_mut` will obtain a mutable references to an owned +/// value, cloning if necessary. +/// +/// # Example +/// +/// ```rust +/// use std::borrow::Cow; +/// +/// fn abs_all(input: &mut Cow<[int]>) { +/// for i in 0..input.len() { +/// let v = input[i]; +/// if v < 0 { +/// // clones into a vector the first time (if not already owned) +/// input.to_mut()[i] = -v; +/// } +/// } +/// } +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned { + /// Borrowed data. + #[stable(feature = "rust1", since = "1.0.0")] + Borrowed(&'a B), + + /// Owned data. + #[stable(feature = "rust1", since = "1.0.0")] + Owned(::Owned) +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned { + fn clone(&self) -> Cow<'a, B> { + match *self { + Borrowed(b) => Borrowed(b), + Owned(ref o) => { + let b: &B = o.borrow(); + Owned(b.to_owned()) + }, + } + } +} + +impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned { + /// Acquire a mutable reference to the owned form of the data. + /// + /// Copies the data if it is not already owned. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn to_mut(&mut self) -> &mut ::Owned { + match *self { + Borrowed(borrowed) => { + *self = Owned(borrowed.to_owned()); + self.to_mut() + } + Owned(ref mut owned) => owned + } + } + + /// Extract the owned data. + /// + /// Copies the data if it is not already owned. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn into_owned(self) -> ::Owned { + match self { + Borrowed(borrowed) => borrowed.to_owned(), + Owned(owned) => owned + } + } + + /// Returns true if this `Cow` wraps a borrowed value + #[deprecated(since = "1.0.0", reason = "match on the enum instead")] + #[unstable(feature = "std_misc")] + pub fn is_borrowed(&self) -> bool { + match *self { + Borrowed(_) => true, + _ => false, + } + } + + /// Returns true if this `Cow` wraps an owned value + #[deprecated(since = "1.0.0", reason = "match on the enum instead")] + #[unstable(feature = "std_misc")] + pub fn is_owned(&self) -> bool { + match *self { + Owned(_) => true, + _ => false, + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Deref for Cow<'a, B> where B: ToOwned { + type Target = B; + + fn deref(&self) -> &B { + match *self { + Borrowed(borrowed) => borrowed, + Owned(ref owned) => owned.borrow() + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Ord for Cow<'a, B> where B: Ord + ToOwned { + #[inline] + fn cmp(&self, other: &Cow<'a, B>) -> Ordering { + Ord::cmp(&**self, &**other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq> for Cow<'a, B> where + B: PartialEq + ToOwned, C: ToOwned, +{ + #[inline] + fn eq(&self, other: &Cow<'b, C>) -> bool { + PartialEq::eq(&**self, &**other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where B: PartialOrd + ToOwned, +{ + #[inline] + fn partial_cmp(&self, other: &Cow<'a, B>) -> Option { + PartialOrd::partial_cmp(&**self, &**other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where + B: fmt::Debug + ToOwned, + ::Owned: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Borrowed(ref b) => fmt::Debug::fmt(b, f), + Owned(ref o) => fmt::Debug::fmt(o, f), + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where + B: fmt::Display + ToOwned, + ::Owned: fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Borrowed(ref b) => fmt::Display::fmt(b, f), + Owned(ref o) => fmt::Display::fmt(o, f), + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized, S: Hasher> Hash for Cow<'a, B> where B: Hash + ToOwned +{ + #[inline] + fn hash(&self, state: &mut S) { + Hash::hash(&**self, state) + } +} + +/// Trait for moving into a `Cow` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { + /// Moves `self` into `Cow` + #[stable(feature = "rust1", since = "1.0.0")] + fn into_cow(self) -> Cow<'a, B>; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned { + fn into_cow(self) -> Cow<'a, B> { + self + } +} diff --git a/src/libcollections/borrow_stage0.rs b/src/libcollections/borrow_stage0.rs new file mode 100644 index 0000000000000..c1d74b16ce6bc --- /dev/null +++ b/src/libcollections/borrow_stage0.rs @@ -0,0 +1,313 @@ +// Copyright 2014 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. + +//! A module for working with borrowed data. + +#![stable(feature = "rust1", since = "1.0.0")] + +use core::clone::Clone; +use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; +use core::hash::{Hash, Hasher}; +use core::marker::Sized; +use core::ops::Deref; +use core::option::Option; + +use fmt; +use alloc::{rc, arc}; + +use self::Cow::*; + +/// A trait for borrowing data. +/// +/// In general, there may be several ways to "borrow" a piece of data. The +/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T` +/// (a mutable borrow). But types like `Vec` provide additional kinds of +/// borrows: the borrowed slices `&[T]` and `&mut [T]`. +/// +/// When writing generic code, it is often desirable to abstract over all ways +/// of borrowing data from a given type. That is the role of the `Borrow` +/// trait: if `T: Borrow`, then `&U` can be borrowed from `&T`. A given +/// type can be borrowed as multiple different types. In particular, `Vec: +/// Borrow>` and `Vec: Borrow<[T]>`. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Borrow { + /// Immutably borrow from an owned value. + #[stable(feature = "rust1", since = "1.0.0")] + fn borrow(&self) -> &Borrowed; +} + +/// A trait for mutably borrowing data. +/// +/// Similar to `Borrow`, but for mutable borrows. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait BorrowMut : Borrow { + /// Mutably borrow from an owned value. + #[stable(feature = "rust1", since = "1.0.0")] + fn borrow_mut(&mut self) -> &mut Borrowed; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Borrow for T { + fn borrow(&self) -> &T { self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl BorrowMut for T { + fn borrow_mut(&mut self) -> &mut T { self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Borrow for &'a T { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Borrow for &'a mut T { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> BorrowMut for &'a mut T { + fn borrow_mut(&mut self) -> &mut T { &mut **self } +} + +impl Borrow for rc::Rc { + fn borrow(&self) -> &T { &**self } +} + +impl Borrow for arc::Arc { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Borrow for Cow<'a, B> where B: ToOwned, ::Owned: 'a { + fn borrow(&self) -> &B { + &**self + } +} + +/// A generalization of Clone to borrowed data. +/// +/// Some types make it possible to go from borrowed to owned, usually by +/// implementing the `Clone` trait. But `Clone` works only for going from `&T` +/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data +/// from any borrow of a given type. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait ToOwned { + #[stable(feature = "rust1", since = "1.0.0")] + type Owned: Borrow; + + /// Create owned data from borrowed data, usually by copying. + #[stable(feature = "rust1", since = "1.0.0")] + fn to_owned(&self) -> Self::Owned; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ToOwned for T where T: Clone { + type Owned = T; + fn to_owned(&self) -> T { self.clone() } +} + +/// A clone-on-write smart pointer. +/// +/// The type `Cow` is a smart pointer providing clone-on-write functionality: it +/// can enclose and provide immutable access to borrowed data, and clone the +/// data lazily when mutation or ownership is required. The type is designed to +/// work with general borrowed data via the `Borrow` trait. +/// +/// `Cow` implements both `Deref`, which means that you can call +/// non-mutating methods directly on the data it encloses. If mutation +/// is desired, `to_mut` will obtain a mutable references to an owned +/// value, cloning if necessary. +/// +/// # Example +/// +/// ```rust +/// use std::borrow::Cow; +/// +/// fn abs_all(input: &mut Cow<[int]>) { +/// for i in 0..input.len() { +/// let v = input[i]; +/// if v < 0 { +/// // clones into a vector the first time (if not already owned) +/// input.to_mut()[i] = -v; +/// } +/// } +/// } +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned { + /// Borrowed data. + #[stable(feature = "rust1", since = "1.0.0")] + Borrowed(&'a B), + + /// Owned data. + #[stable(feature = "rust1", since = "1.0.0")] + Owned(::Owned) +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned { + fn clone(&self) -> Cow<'a, B> { + match *self { + Borrowed(b) => Borrowed(b), + Owned(ref o) => { + let b: &B = o.borrow(); + Owned(b.to_owned()) + }, + } + } +} + +impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned, ::Owned: 'a { + /// Acquire a mutable reference to the owned form of the data. + /// + /// Copies the data if it is not already owned. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn to_mut(&mut self) -> &mut ::Owned where ::Owned: 'a { + match *self { + Borrowed(borrowed) => { + *self = Owned(borrowed.to_owned()); + self.to_mut() + } + Owned(ref mut owned) => owned + } + } + + /// Extract the owned data. + /// + /// Copies the data if it is not already owned. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn into_owned(self) -> ::Owned { + match self { + Borrowed(borrowed) => borrowed.to_owned(), + Owned(owned) => owned + } + } + + /// Returns true if this `Cow` wraps a borrowed value + #[deprecated(since = "1.0.0", reason = "match on the enum instead")] + #[unstable(feature = "std_misc")] + pub fn is_borrowed(&self) -> bool { + match *self { + Borrowed(_) => true, + _ => false, + } + } + + /// Returns true if this `Cow` wraps an owned value + #[deprecated(since = "1.0.0", reason = "match on the enum instead")] + #[unstable(feature = "std_misc")] + pub fn is_owned(&self) -> bool { + match *self { + Owned(_) => true, + _ => false, + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Deref for Cow<'a, B> where + B: ToOwned, ::Owned: 'a +{ + type Target = B; + + fn deref(&self) -> &B { + match *self { + Borrowed(borrowed) => borrowed, + Owned(ref owned) => owned.borrow() + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned, ::Owned: 'a {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> Ord for Cow<'a, B> where + B: Ord + ToOwned, ::Owned: 'a +{ + #[inline] + fn cmp(&self, other: &Cow<'a, B>) -> Ordering { + Ord::cmp(&**self, &**other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq> for Cow<'a, B> where + B: PartialEq + ToOwned, C: ToOwned, + ::Owned: 'a, ::Owned: 'b, +{ + #[inline] + fn eq(&self, other: &Cow<'b, C>) -> bool { + PartialEq::eq(&**self, &**other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where + B: PartialOrd + ToOwned, ::Owned: 'a +{ + #[inline] + fn partial_cmp(&self, other: &Cow<'a, B>) -> Option { + PartialOrd::partial_cmp(&**self, &**other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where + B: fmt::Debug + ToOwned, + ::Owned: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Borrowed(ref b) => fmt::Debug::fmt(b, f), + Owned(ref o) => fmt::Debug::fmt(o, f), + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where + B: fmt::Display + ToOwned, + ::Owned: fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Borrowed(ref b) => fmt::Display::fmt(b, f), + Owned(ref o) => fmt::Display::fmt(o, f), + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized, S: Hasher> Hash for Cow<'a, B> where + B: Hash + ToOwned, ::Owned: 'a +{ + #[inline] + fn hash(&self, state: &mut S) { + Hash::hash(&**self, state) + } +} + +/// Trait for moving into a `Cow` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { + /// Moves `self` into `Cow` + #[stable(feature = "rust1", since = "1.0.0")] + fn into_cow(self) -> Cow<'a, B>; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned { + fn into_cow(self) -> Cow<'a, B> { + self + } +} diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 747211e923859..6b980d473b590 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -19,7 +19,6 @@ use self::Entry::*; use core::prelude::*; -use core::borrow::BorrowFrom; use core::cmp::Ordering; use core::default::Default; use core::fmt::Debug; @@ -29,6 +28,7 @@ use core::ops::{Index, IndexMut}; use core::{iter, fmt, mem}; use Bound::{self, Included, Excluded, Unbounded}; +use borrow::Borrow; use ring_buf::RingBuf; use self::Continuation::{Continue, Finished}; @@ -208,7 +208,7 @@ impl BTreeMap { /// assert_eq!(map.get(&2), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn get(&self, key: &Q) -> Option<&V> where Q: BorrowFrom + Ord { + pub fn get(&self, key: &Q) -> Option<&V> where K: Borrow, Q: Ord { let mut cur_node = &self.root; loop { match Node::search(cur_node, key) { @@ -240,7 +240,7 @@ impl BTreeMap { /// assert_eq!(map.contains_key(&2), false); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn contains_key(&self, key: &Q) -> bool where Q: BorrowFrom + Ord { + pub fn contains_key(&self, key: &Q) -> bool where K: Borrow, Q: Ord { self.get(key).is_some() } @@ -264,7 +264,7 @@ impl BTreeMap { /// ``` // See `get` for implementation notes, this is basically a copy-paste with mut's added #[stable(feature = "rust1", since = "1.0.0")] - pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> where Q: BorrowFrom + Ord { + pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> where K: Borrow, Q: Ord { // temp_node is a Borrowck hack for having a mutable value outlive a loop iteration let mut temp_node = &mut self.root; loop { @@ -434,7 +434,7 @@ impl BTreeMap { /// assert_eq!(map.remove(&1), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn remove(&mut self, key: &Q) -> Option where Q: BorrowFrom + Ord { + pub fn remove(&mut self, key: &Q) -> Option where K: Borrow, Q: Ord { // See `swap` for a more thorough description of the stuff going on in here let mut stack = stack::PartialSearchStack::new(self); loop { @@ -903,7 +903,7 @@ impl Debug for BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] impl Index for BTreeMap - where Q: BorrowFrom + Ord + where K: Borrow, Q: Ord { type Output = V; @@ -914,7 +914,7 @@ impl Index for BTreeMap #[stable(feature = "rust1", since = "1.0.0")] impl IndexMut for BTreeMap - where Q: BorrowFrom + Ord + where K: Borrow, Q: Ord { fn index_mut(&mut self, key: &Q) -> &mut V { self.get_mut(key).expect("no entry found for key") diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index 24523d4dcc9d3..8f5ee35fcb265 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -18,7 +18,6 @@ pub use self::TraversalItem::*; use core::prelude::*; -use core::borrow::BorrowFrom; use core::cmp::Ordering::{Greater, Less, Equal}; use core::iter::Zip; use core::ops::{Deref, DerefMut, Index, IndexMut}; @@ -26,6 +25,8 @@ use core::ptr::Unique; use core::{slice, mem, ptr, cmp, num, raw}; use alloc::heap; +use borrow::Borrow; + /// Represents the result of an Insertion: either the item fit, or the node had to split pub enum InsertionResult { /// The inserted element fit @@ -543,7 +544,7 @@ impl Node { /// `Found` will be yielded with the matching index. If it doesn't find an exact match, /// `GoDown` will be yielded with the index of the subtree the key must lie in. pub fn search>>(node: NodeRef, key: &Q) - -> SearchResult where Q: BorrowFrom + Ord { + -> SearchResult where K: Borrow, Q: Ord { // FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V). // For the B configured as of this writing (B = 6), binary search was *significantly* // worse for usizes. @@ -1491,9 +1492,9 @@ macro_rules! node_slice_impl { impl<'a, K: Ord + 'a, V: 'a> $NodeSlice<'a, K, V> { /// Performs linear search in a slice. Returns a tuple of (index, is_exact_match). fn search_linear(&self, key: &Q) -> (usize, bool) - where Q: BorrowFrom + Ord { + where K: Borrow, Q: Ord { for (i, k) in self.keys.iter().enumerate() { - match key.cmp(BorrowFrom::borrow_from(k)) { + match key.cmp(k.borrow()) { Greater => {}, Equal => return (i, true), Less => return (i, false), diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 7ef887b70cc6c..cf96ef49c7f59 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -13,7 +13,6 @@ use core::prelude::*; -use core::borrow::BorrowFrom; use core::cmp::Ordering::{self, Less, Greater, Equal}; use core::default::Default; use core::fmt::Debug; @@ -21,6 +20,7 @@ use core::fmt; use core::iter::{Peekable, Map, FromIterator, IntoIterator}; use core::ops::{BitOr, BitAnd, BitXor, Sub}; +use borrow::Borrow; use btree_map::{BTreeMap, Keys}; use Bound; @@ -336,7 +336,7 @@ impl BTreeSet { /// assert_eq!(set.contains(&4), false); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn contains(&self, value: &Q) -> bool where Q: BorrowFrom + Ord { + pub fn contains(&self, value: &Q) -> bool where T: Borrow, Q: Ord { self.map.contains_key(value) } @@ -466,7 +466,7 @@ impl BTreeSet { /// assert_eq!(set.remove(&2), false); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn remove(&mut self, value: &Q) -> bool where Q: BorrowFrom + Ord { + pub fn remove(&mut self, value: &Q) -> bool where T: Borrow, Q: Ord { self.map.remove(value).is_some() } } diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index cacbf3bce80f0..f5fbd10ceebfe 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -81,6 +81,13 @@ pub mod string; pub mod vec; pub mod vec_map; +#[cfg(stage0)] +#[path = "borrow_stage0.rs"] +pub mod borrow; + +#[cfg(not(stage0))] +pub mod borrow; + #[unstable(feature = "collections", reason = "RFC 509")] pub mod bitv { diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 06ae8127c00fb..a0cb98267fa77 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -88,7 +88,6 @@ #![stable(feature = "rust1", since = "1.0.0")] use alloc::boxed::Box; -use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned}; use core::clone::Clone; use core::cmp::Ordering::{self, Greater, Less}; use core::cmp::{self, Ord, PartialEq}; @@ -105,6 +104,7 @@ use core::result::Result; use core::slice as core_slice; use self::Direction::*; +use borrow::{Borrow, BorrowMut, ToOwned}; use vec::Vec; pub use core::slice::{Chunks, AsSlice, Windows}; @@ -1175,18 +1175,19 @@ impl ElementSwaps { // Standard trait implementations for slices //////////////////////////////////////////////////////////////////////////////// -#[unstable(feature = "collections", reason = "trait is unstable")] -impl BorrowFrom> for [T] { - fn borrow_from(owned: &Vec) -> &[T] { &owned[] } +#[stable(feature = "rust1", since = "1.0.0")] +impl Borrow<[T]> for Vec { + fn borrow(&self) -> &[T] { &self[] } } -#[unstable(feature = "collections", reason = "trait is unstable")] -impl BorrowFromMut> for [T] { - fn borrow_from_mut(owned: &mut Vec) -> &mut [T] { &mut owned[] } +#[stable(feature = "rust1", since = "1.0.0")] +impl BorrowMut<[T]> for Vec { + fn borrow_mut(&mut self) -> &mut [T] { &mut self[] } } -#[unstable(feature = "collections", reason = "trait is unstable")] -impl ToOwned> for [T] { +#[stable(feature = "rust1", since = "1.0.0")] +impl ToOwned for [T] { + type Owned = Vec; fn to_owned(&self) -> Vec { self.to_vec() } } diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 2d4dc2bcf30d3..95fd233dc97ec 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -55,7 +55,6 @@ use self::RecompositionState::*; use self::DecompositionType::*; -use core::borrow::{BorrowFrom, ToOwned}; use core::char::CharExt; use core::clone::Clone; use core::iter::AdditiveIterator; @@ -68,6 +67,7 @@ use core::slice::AsSlice; use core::str as core_str; use unicode::str::{UnicodeStr, Utf16Encoder}; +use borrow::{Borrow, ToOwned}; use ring_buf::RingBuf; use slice::SliceExt; use string::String; @@ -386,13 +386,14 @@ macro_rules! utf8_acc_cont_byte { ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as u32) } -#[unstable(feature = "collections", reason = "trait is unstable")] -impl BorrowFrom for str { - fn borrow_from(owned: &String) -> &str { &owned[] } +#[stable(feature = "rust1", since = "1.0.0")] +impl Borrow for String { + fn borrow(&self) -> &str { &self[] } } -#[unstable(feature = "collections", reason = "trait is unstable")] -impl ToOwned for str { +#[stable(feature = "rust1", since = "1.0.0")] +impl ToOwned for str { + type Owned = String; fn to_owned(&self) -> String { unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 69fd28d172368..f03ee671ffa63 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -16,7 +16,6 @@ use core::prelude::*; -use core::borrow::{Cow, IntoCow}; use core::default::Default; use core::error::Error; use core::fmt; @@ -29,6 +28,7 @@ use core::raw::Slice as RawSlice; use unicode::str as unicode_str; use unicode::str::Utf16Item; +use borrow::{Cow, IntoCow}; use str::{self, CharRange, FromStr, Utf8Error}; use vec::{DerefVec, Vec, as_vec}; @@ -142,7 +142,7 @@ impl String { /// assert_eq!(output.as_slice(), "Hello \u{FFFD}World"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> CowString<'a> { + pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> { let mut i = 0; match str::from_utf8(v) { Ok(s) => return Cow::Borrowed(s), @@ -780,10 +780,10 @@ macro_rules! impl_eq { } impl_eq! { String, &'a str } -impl_eq! { CowString<'a>, String } +impl_eq! { Cow<'a, str>, String } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b> PartialEq<&'b str> for CowString<'a> { +impl<'a, 'b> PartialEq<&'b str> for Cow<'a, str> { #[inline] fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) } #[inline] @@ -791,11 +791,11 @@ impl<'a, 'b> PartialEq<&'b str> for CowString<'a> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b> PartialEq> for &'b str { +impl<'a, 'b> PartialEq> for &'b str { #[inline] - fn eq(&self, other: &CowString<'a>) -> bool { PartialEq::eq(&**self, &**other) } + fn eq(&self, other: &Cow<'a, str>) -> bool { PartialEq::eq(&**self, &**other) } #[inline] - fn ne(&self, other: &CowString<'a>) -> bool { PartialEq::ne(&**self, &**other) } + fn ne(&self, other: &Cow<'a, str>) -> bool { PartialEq::ne(&**self, &**other) } } #[unstable(feature = "collections", reason = "waiting on Str stabilization")] @@ -958,31 +958,34 @@ impl ToString for T { } } -impl IntoCow<'static, String, str> for String { +#[stable(feature = "rust1", since = "1.0.0")] +impl IntoCow<'static, str> for String { #[inline] - fn into_cow(self) -> CowString<'static> { + fn into_cow(self) -> Cow<'static, str> { Cow::Owned(self) } } -impl<'a> IntoCow<'a, String, str> for &'a str { +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> IntoCow<'a, str> for &'a str { #[inline] - fn into_cow(self) -> CowString<'a> { + fn into_cow(self) -> Cow<'a, str> { Cow::Borrowed(self) } } -/// A clone-on-write string -#[stable(feature = "rust1", since = "1.0.0")] -pub type CowString<'a> = Cow<'a, String, str>; - -impl<'a> Str for CowString<'a> { +impl<'a> Str for Cow<'a, str> { #[inline] fn as_slice<'b>(&'b self) -> &'b str { &**self } } +/// A clone-on-write string +#[deprecated(since = "1.0.0", reason = "use Cow<'a, str> instead")] +#[stable(feature = "rust1", since = "1.0.0")] +pub type CowString<'a> = Cow<'a, str>; + #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Write for String { #[inline] diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index bde733644b5b5..df6aa560257b6 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -50,7 +50,6 @@ use core::prelude::*; use alloc::boxed::Box; use alloc::heap::{EMPTY, allocate, reallocate, deallocate}; -use core::borrow::{Cow, IntoCow}; use core::cmp::max; use core::cmp::{Ordering}; use core::default::Default; @@ -68,6 +67,8 @@ use core::raw::Slice as RawSlice; use core::slice; use core::usize; +use borrow::{Cow, IntoCow}; + /// A growable list type, written `Vec` but pronounced 'vector.' /// /// # Examples @@ -1517,34 +1518,34 @@ macro_rules! impl_eq { impl_eq! { Vec, &'b [B] } impl_eq! { Vec, &'b mut [B] } -impl<'a, A, B> PartialEq> for CowVec<'a, A> where A: PartialEq + Clone { +impl<'a, A, B> PartialEq> for Cow<'a, [A]> where A: PartialEq + Clone { #[inline] fn eq(&self, other: &Vec) -> bool { PartialEq::eq(&**self, &**other) } #[inline] fn ne(&self, other: &Vec) -> bool { PartialEq::ne(&**self, &**other) } } -impl<'a, A, B> PartialEq> for Vec where A: Clone, B: PartialEq { +impl<'a, A, B> PartialEq> for Vec where A: Clone, B: PartialEq { #[inline] - fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) } + fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) } #[inline] - fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) } + fn ne(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::ne(&**self, &**other) } } macro_rules! impl_eq_for_cowvec { ($rhs:ty) => { - impl<'a, 'b, A, B> PartialEq<$rhs> for CowVec<'a, A> where A: PartialEq + Clone { + impl<'a, 'b, A, B> PartialEq<$rhs> for Cow<'a, [A]> where A: PartialEq + Clone { #[inline] fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) } #[inline] fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) } } - impl<'a, 'b, A, B> PartialEq> for $rhs where A: Clone, B: PartialEq { + impl<'a, 'b, A, B> PartialEq> for $rhs where A: Clone, B: PartialEq { #[inline] - fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) } + fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) } #[inline] - fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) } + fn ne(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::ne(&**self, &**other) } } } } @@ -1552,8 +1553,7 @@ macro_rules! impl_eq_for_cowvec { impl_eq_for_cowvec! { &'b [B] } impl_eq_for_cowvec! { &'b mut [B] } -#[unstable(feature = "collections", - reason = "waiting on PartialOrd stability")] +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for Vec { #[inline] fn partial_cmp(&self, other: &Vec) -> Option { @@ -1561,10 +1561,10 @@ impl PartialOrd for Vec { } } -#[unstable(feature = "collections", reason = "waiting on Eq stability")] +#[stable(feature = "rust1", since = "1.0.0")] impl Eq for Vec {} -#[unstable(feature = "collections", reason = "waiting on Ord stability")] +#[stable(feature = "rust1", since = "1.0.0")] impl Ord for Vec { #[inline] fn cmp(&self, other: &Vec) -> Ordering { @@ -1643,26 +1643,26 @@ impl fmt::Debug for Vec { // Clone-on-write //////////////////////////////////////////////////////////////////////////////// -#[unstable(feature = "collections", - reason = "unclear how valuable this alias is")] /// A clone-on-write vector -pub type CowVec<'a, T> = Cow<'a, Vec, [T]>; +#[deprecated(since = "1.0.0", reason = "use Cow<'a, [T]> instead")] +#[unstable(feature = "collections")] +pub type CowVec<'a, T> = Cow<'a, [T]>; #[unstable(feature = "collections")] -impl<'a, T> FromIterator for CowVec<'a, T> where T: Clone { +impl<'a, T> FromIterator for Cow<'a, [T]> where T: Clone { fn from_iter>(it: I) -> CowVec<'a, T> { Cow::Owned(FromIterator::from_iter(it)) } } -impl<'a, T: 'a> IntoCow<'a, Vec, [T]> for Vec where T: Clone { - fn into_cow(self) -> CowVec<'a, T> { +impl<'a, T: 'a> IntoCow<'a, [T]> for Vec where T: Clone { + fn into_cow(self) -> Cow<'a, [T]> { Cow::Owned(self) } } -impl<'a, T> IntoCow<'a, Vec, [T]> for &'a [T] where T: Clone { - fn into_cow(self) -> CowVec<'a, T> { +impl<'a, T> IntoCow<'a, [T]> for &'a [T] where T: Clone { + fn into_cow(self) -> Cow<'a, [T]> { Cow::Borrowed(self) } } diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs deleted file mode 100644 index 035443e9c3f35..0000000000000 --- a/src/libcore/borrow.rs +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright 2014 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. - -//! A module for working with borrowed data. -//! -//! # The `BorrowFrom` traits -//! -//! In general, there may be several ways to "borrow" a piece of data. The -//! typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T` -//! (a mutable borrow). But types like `Vec` provide additional kinds of -//! borrows: the borrowed slices `&[T]` and `&mut [T]`. -//! -//! When writing generic code, it is often desirable to abstract over all ways -//! of borrowing data from a given type. That is the role of the `BorrowFrom` -//! trait: if `T: BorrowFrom`, then `&T` can be borrowed from `&U`. A given -//! type can be borrowed as multiple different types. In particular, `Vec: -//! BorrowFrom>` and `[T]: BorrowFrom>`. -//! -//! # The `ToOwned` trait -//! -//! Some types make it possible to go from borrowed to owned, usually by -//! implementing the `Clone` trait. But `Clone` works only for going from `&T` -//! to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data -//! from any borrow of a given type. -//! -//! # The `Cow` (clone-on-write) type -//! -//! The type `Cow` is a smart pointer providing clone-on-write functionality: it -//! can enclose and provide immutable access to borrowed data, and clone the -//! data lazily when mutation or ownership is required. The type is designed to -//! work with general borrowed data via the `BorrowFrom` trait. -//! -//! `Cow` implements both `Deref`, which means that you can call -//! non-mutating methods directly on the data it encloses. If mutation -//! is desired, `to_mut` will obtain a mutable references to an owned -//! value, cloning if necessary. - -#![unstable(feature = "core", - reason = "recently added as part of collections reform")] - -use clone::Clone; -use cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; -use fmt; -use marker::Sized; -use ops::Deref; -use option::Option; -use self::Cow::*; - -/// A trait for borrowing data. -#[old_orphan_check] -pub trait BorrowFrom { - /// Immutably borrow from an owned value. - fn borrow_from(owned: &Owned) -> &Self; -} - -/// A trait for mutably borrowing data. -#[old_orphan_check] -pub trait BorrowFromMut : BorrowFrom { - /// Mutably borrow from an owned value. - fn borrow_from_mut(owned: &mut Owned) -> &mut Self; -} - -impl BorrowFrom for T { - fn borrow_from(owned: &T) -> &T { owned } -} - -impl BorrowFromMut for T { - fn borrow_from_mut(owned: &mut T) -> &mut T { owned } -} - -impl<'a, T: ?Sized> BorrowFrom<&'a T> for T { - fn borrow_from<'b>(owned: &'b &'a T) -> &'b T { &**owned } -} - -impl<'a, T: ?Sized> BorrowFrom<&'a mut T> for T { - fn borrow_from<'b>(owned: &'b &'a mut T) -> &'b T { &**owned } -} - -impl<'a, T: ?Sized> BorrowFromMut<&'a mut T> for T { - fn borrow_from_mut<'b>(owned: &'b mut &'a mut T) -> &'b mut T { &mut **owned } -} - -impl<'a, T, B: ?Sized> BorrowFrom> for B where B: ToOwned { - fn borrow_from<'b>(owned: &'b Cow<'a, T, B>) -> &'b B { - &**owned - } -} - -/// Trait for moving into a `Cow` -#[old_orphan_check] -pub trait IntoCow<'a, T, B: ?Sized> { - /// Moves `self` into `Cow` - fn into_cow(self) -> Cow<'a, T, B>; -} - -impl<'a, T, B: ?Sized> IntoCow<'a, T, B> for Cow<'a, T, B> where B: ToOwned { - fn into_cow(self) -> Cow<'a, T, B> { - self - } -} - -/// A generalization of Clone to borrowed data. -#[old_orphan_check] -pub trait ToOwned: BorrowFrom { - /// Create owned data from borrowed data, usually by copying. - fn to_owned(&self) -> Owned; -} - -impl ToOwned for T where T: Clone { - fn to_owned(&self) -> T { self.clone() } -} - -/// A clone-on-write smart pointer. -/// -/// # Example -/// -/// ```rust -/// use std::borrow::Cow; -/// -/// fn abs_all(input: &mut Cow, [int]>) { -/// for i in 0..input.len() { -/// let v = input[i]; -/// if v < 0 { -/// // clones into a vector the first time (if not already owned) -/// input.to_mut()[i] = -v; -/// } -/// } -/// } -/// ``` -pub enum Cow<'a, T, B: ?Sized + 'a> where B: ToOwned { - /// Borrowed data. - Borrowed(&'a B), - - /// Owned data. - Owned(T) -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> Clone for Cow<'a, T, B> where B: ToOwned { - fn clone(&self) -> Cow<'a, T, B> { - match *self { - Borrowed(b) => Borrowed(b), - Owned(ref o) => { - let b: &B = BorrowFrom::borrow_from(o); - Owned(b.to_owned()) - }, - } - } -} - -impl<'a, T, B: ?Sized> Cow<'a, T, B> where B: ToOwned { - /// Acquire a mutable reference to the owned form of the data. - /// - /// Copies the data if it is not already owned. - pub fn to_mut(&mut self) -> &mut T { - match *self { - Borrowed(borrowed) => { - *self = Owned(borrowed.to_owned()); - self.to_mut() - } - Owned(ref mut owned) => owned - } - } - - /// Extract the owned data. - /// - /// Copies the data if it is not already owned. - pub fn into_owned(self) -> T { - match self { - Borrowed(borrowed) => borrowed.to_owned(), - Owned(owned) => owned - } - } - - /// Returns true if this `Cow` wraps a borrowed value - pub fn is_borrowed(&self) -> bool { - match *self { - Borrowed(_) => true, - _ => false, - } - } - - /// Returns true if this `Cow` wraps an owned value - pub fn is_owned(&self) -> bool { - match *self { - Owned(_) => true, - _ => false, - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> Deref for Cow<'a, T, B> where B: ToOwned { - type Target = B; - - fn deref(&self) -> &B { - match *self { - Borrowed(borrowed) => borrowed, - Owned(ref owned) => BorrowFrom::borrow_from(owned) - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> Eq for Cow<'a, T, B> where B: Eq + ToOwned {} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> Ord for Cow<'a, T, B> where B: Ord + ToOwned { - #[inline] - fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering { - Ord::cmp(&**self, &**other) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T, U, B: ?Sized, C: ?Sized> PartialEq> for Cow<'a, T, B> where - B: PartialEq + ToOwned, - C: ToOwned, -{ - #[inline] - fn eq(&self, other: &Cow<'b, U, C>) -> bool { - PartialEq::eq(&**self, &**other) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned { - #[inline] - fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option { - PartialOrd::partial_cmp(&**self, &**other) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> fmt::Debug for Cow<'a, T, B> where - B: fmt::Debug + ToOwned, - T: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Borrowed(ref b) => fmt::Debug::fmt(b, f), - Owned(ref o) => fmt::Debug::fmt(o, f), - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> fmt::Display for Cow<'a, T, B> where - B: fmt::Display + ToOwned, - T: fmt::Display, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Borrowed(ref b) => fmt::Display::fmt(b, f), - Owned(ref o) => fmt::Display::fmt(o, f), - } - } -} diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index a5d2618eff948..28e14836a0492 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -61,7 +61,6 @@ use prelude::*; -use borrow::{Cow, ToOwned}; use default::Default; use mem; use num::Int; @@ -243,12 +242,3 @@ impl Hash for *mut T { (*self as uint).hash(state); } } - -impl<'a, T, B: ?Sized, S: Hasher> Hash for Cow<'a, T, B> - where B: Hash + ToOwned -{ - #[inline] - fn hash(&self, state: &mut S) { - Hash::hash(&**self, state) - } -} diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index f0c60ffe4bf66..3c58480ff0cfa 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -126,7 +126,6 @@ pub mod default; pub mod any; pub mod atomic; -pub mod borrow; pub mod cell; pub mod char; pub mod panicking; diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 230deabee0034..28a97b1e8dbb3 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -358,7 +358,7 @@ impl<'a> Id<'a> { /// /// Passing an invalid string (containing spaces, brackets, /// quotes, ...) will return an empty `Err` value. - pub fn new>(name: Name) -> Result, ()> { + pub fn new>(name: Name) -> Result, ()> { let name = name.into_cow(); { let mut chars = name.chars(); @@ -427,11 +427,11 @@ pub trait Labeller<'a,N,E> { } impl<'a> LabelText<'a> { - pub fn label>(s: S) -> LabelText<'a> { + pub fn label>(s: S) -> LabelText<'a> { LabelStr(s.into_cow()) } - pub fn escaped>(s: S) -> LabelText<'a> { + pub fn escaped>(s: S) -> LabelText<'a> { EscStr(s.into_cow()) } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index e3eda02b0a842..60ae646e2c799 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -68,7 +68,7 @@ use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet}; use util::nodemap::{FnvHashMap}; use arena::TypedArena; -use std::borrow::{BorrowFrom, Cow}; +use std::borrow::{Borrow, Cow}; use std::cell::{Cell, RefCell}; use std::cmp; use std::fmt; @@ -986,9 +986,9 @@ impl<'tcx, S: Writer + Hasher> Hash for InternedTy<'tcx> { } } -impl<'tcx> BorrowFrom> for sty<'tcx> { - fn borrow_from<'a>(ty: &'a InternedTy<'tcx>) -> &'a sty<'tcx> { - &ty.ty.sty +impl<'tcx> Borrow> for InternedTy<'tcx> { + fn borrow<'a>(&'a self) -> &'a sty<'tcx> { + &self.ty.sty } } diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 1b9f8b9901723..9d3ffb114c121 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -14,7 +14,7 @@ use self::Entry::*; use self::SearchResult::*; use self::VacantEntryState::*; -use borrow::BorrowFrom; +use borrow::Borrow; use clone::Clone; use cmp::{max, Eq, PartialEq}; use default::Default; @@ -453,18 +453,18 @@ impl HashMap /// If you already have the hash for the key lying around, use /// search_hashed. fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> Option> - where Q: BorrowFrom + Eq + Hash + where K: Borrow, Q: Eq + Hash { let hash = self.make_hash(q); - search_hashed(&self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k))) + search_hashed(&self.table, hash, |k| q.eq(k.borrow())) .into_option() } fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> Option> - where Q: BorrowFrom + Eq + Hash + where K: Borrow, Q: Eq + Hash { let hash = self.make_hash(q); - search_hashed(&mut self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k))) + search_hashed(&mut self.table, hash, |k| q.eq(k.borrow())) .into_option() } @@ -1037,7 +1037,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self, k: &Q) -> Option<&V> - where Q: Hash + Eq + BorrowFrom + where K: Borrow, Q: Hash + Eq { self.search(k).map(|bucket| bucket.into_refs().1) } @@ -1060,7 +1060,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains_key(&self, k: &Q) -> bool - where Q: Hash + Eq + BorrowFrom + where K: Borrow, Q: Hash + Eq { self.search(k).is_some() } @@ -1086,7 +1086,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> - where Q: Hash + Eq + BorrowFrom + where K: Borrow, Q: Hash + Eq { self.search_mut(k).map(|bucket| bucket.into_mut_refs().1) } @@ -1138,7 +1138,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, k: &Q) -> Option - where Q: Hash + Eq + BorrowFrom + where K: Borrow, Q: Hash + Eq { if self.table.size() == 0 { return None @@ -1247,8 +1247,8 @@ impl Default for HashMap #[stable(feature = "rust1", since = "1.0.0")] impl Index for HashMap - where K: Eq + Hash, - Q: Eq + Hash + BorrowFrom, + where K: Eq + Hash + Borrow, + Q: Eq + Hash, S: HashState, H: hash::Hasher { @@ -1262,8 +1262,8 @@ impl Index for HashMap #[stable(feature = "rust1", since = "1.0.0")] impl IndexMut for HashMap - where K: Eq + Hash, - Q: Eq + Hash + BorrowFrom, + where K: Eq + Hash + Borrow, + Q: Eq + Hash, S: HashState, H: hash::Hasher { diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 5fbbcb3b347af..7befaa8c368c6 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -10,7 +10,7 @@ // // ignore-lexer-test FIXME #15883 -use borrow::BorrowFrom; +use borrow::Borrow; use clone::Clone; use cmp::{Eq, PartialEq}; use core::marker::Sized; @@ -462,7 +462,7 @@ impl HashSet /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains(&self, value: &Q) -> bool - where Q: BorrowFrom + Hash + Eq + where T: Borrow, Q: Hash + Eq { self.map.contains_key(value) } @@ -572,7 +572,7 @@ impl HashSet /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, value: &Q) -> bool - where Q: BorrowFrom + Hash + Eq + where T: Borrow, Q: Hash + Eq { self.map.remove(value).is_some() } diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 1d14b141778f0..8c29b11cb99f9 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -34,7 +34,7 @@ use core::prelude::*; -use core::borrow::{BorrowFrom, ToOwned}; +use borrow::{Borrow, ToOwned}; use fmt::{self, Debug}; use mem; use string::{String, CowString}; @@ -266,11 +266,12 @@ impl Debug for OsStr { } } -impl BorrowFrom for OsStr { - fn borrow_from(owned: &OsString) -> &OsStr { &owned[] } +impl Borrow for OsString { + fn borrow(&self) -> &OsStr { &self[] } } -impl ToOwned for OsStr { +impl ToOwned for OsStr { + type Owned = OsString; fn to_owned(&self) -> OsString { self.to_os_string() } } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 7c9a8a7b4b5ad..fbd403ea593b8 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -161,7 +161,6 @@ extern crate libc; // NB: These reexports are in the order they should be listed in rustdoc pub use core::any; -pub use core::borrow; pub use core::cell; pub use core::clone; #[cfg(not(test))] pub use core::cmp; @@ -184,6 +183,7 @@ pub use core::error; #[cfg(not(test))] pub use alloc::boxed; pub use alloc::rc; +pub use core_collections::borrow; pub use core_collections::fmt; pub use core_collections::slice; pub use core_collections::str; diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 1d992668900f0..1f7129bf361e2 100755 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -108,12 +108,11 @@ use core::prelude::*; use ascii::*; -use borrow::BorrowFrom; +use borrow::{Borrow, ToOwned, Cow}; use cmp; use iter; use mem; use ops::{self, Deref}; -use string::CowString; use vec::Vec; use fmt; @@ -982,12 +981,17 @@ impl ops::Deref for PathBuf { } } -impl BorrowFrom for Path { - fn borrow_from(owned: &PathBuf) -> &Path { - owned.deref() +impl Borrow for PathBuf { + fn borrow(&self) -> &Path { + self.deref() } } +impl ToOwned for Path { + type Owned = PathBuf; + fn to_owned(&self) -> PathBuf { self.to_path_buf() } +} + impl cmp::PartialEq for PathBuf { fn eq(&self, other: &PathBuf) -> bool { self.components() == other.components() @@ -1066,10 +1070,10 @@ impl Path { self.inner.to_str() } - /// Convert a `Path` to a `CowString`. + /// Convert a `Path` to a `Cow`. /// /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER. - pub fn to_string_lossy(&self) -> CowString { + pub fn to_string_lossy(&self) -> Cow { self.inner.to_string_lossy() } diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 511442675194e..5236122f585e1 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -14,7 +14,7 @@ use ast::Name; -use std::borrow::BorrowFrom; +use std::borrow::Borrow; use std::cell::RefCell; use std::cmp::Ordering; use std::collections::HashMap; @@ -79,7 +79,7 @@ impl + Clone + 'static> Interner { } pub fn find(&self, val: &Q) -> Option - where Q: BorrowFrom + Eq + Hash { + where T: Borrow, Q: Eq + Hash { let map = self.map.borrow(); match (*map).get(val) { Some(v) => Some(*v), @@ -128,9 +128,9 @@ impl fmt::Display for RcStr { } } -impl BorrowFrom for str { - fn borrow_from(owned: &RcStr) -> &str { - &owned.string[] +impl Borrow for RcStr { + fn borrow(&self) -> &str { + &self.string[] } } @@ -211,7 +211,7 @@ impl StrInterner { } pub fn find(&self, val: &Q) -> Option - where Q: BorrowFrom + Eq + Hash { + where RcStr: Borrow, Q: Eq + Hash { match (*self.map.borrow()).get(val) { Some(v) => Some(*v), None => None, diff --git a/src/test/compile-fail/ufcs-qpath-missing-params.rs b/src/test/compile-fail/ufcs-qpath-missing-params.rs index 5fa66eb98e1af..f4e18265fd990 100644 --- a/src/test/compile-fail/ufcs-qpath-missing-params.rs +++ b/src/test/compile-fail/ufcs-qpath-missing-params.rs @@ -12,6 +12,5 @@ use std::borrow::IntoCow; fn main() { ::into_cow("foo".to_string()); - //~^ ERROR wrong number of type arguments: expected 2, found 0 + //~^ ERROR wrong number of type arguments: expected 1, found 0 } - diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make/save-analysis/foo.rs index d90219b4221eb..b393afeef39ad 100644 --- a/src/test/run-make/save-analysis/foo.rs +++ b/src/test/run-make/save-analysis/foo.rs @@ -34,7 +34,7 @@ use std::mem::size_of; static uni: &'static str = "Les Miséééééééérables"; static yy: usize = 25us; -static bob: Option> = None; +static bob: Option> = None; // buglink test - see issue #1337. diff --git a/src/test/run-pass/const-polymorphic-paths.rs b/src/test/run-pass/const-polymorphic-paths.rs index f8f92a56adb1a..be4c3272a5b66 100644 --- a/src/test/run-pass/const-polymorphic-paths.rs +++ b/src/test/run-pass/const-polymorphic-paths.rs @@ -100,8 +100,8 @@ tests! { Add::add, fn(i32, i32) -> i32, (5, 6); >::add, fn(i32, i32) -> i32, (5, 6); >::add, fn(i32, i32) -> i32, (5, 6); - >::into_cow, fn(String) -> Cow<'static, String, str>, + >::into_cow, fn(String) -> Cow<'static, str>, ("foo".to_string()); - >::into_cow, fn(String) -> Cow<'static, String, str>, + >::into_cow, fn(String) -> Cow<'static, str>, ("foo".to_string()); } diff --git a/src/test/run-pass/send_str_hashmap.rs b/src/test/run-pass/send_str_hashmap.rs index c58654670d1a3..33e4fa85bcb81 100644 --- a/src/test/run-pass/send_str_hashmap.rs +++ b/src/test/run-pass/send_str_hashmap.rs @@ -13,7 +13,7 @@ extern crate collections; use std::collections::HashMap; use std::borrow::{Cow, IntoCow}; -type SendStr = Cow<'static, String, str>; +type SendStr = Cow<'static, str>; pub fn main() { let mut map: HashMap = HashMap::new(); diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs index 438724a2b06bf..3390369242d13 100644 --- a/src/test/run-pass/send_str_treemap.rs +++ b/src/test/run-pass/send_str_treemap.rs @@ -13,7 +13,7 @@ extern crate collections; use self::collections::BTreeMap; use std::borrow::{Cow, IntoCow}; -type SendStr = Cow<'static, String, str>; +type SendStr = Cow<'static, str>; pub fn main() { let mut map: BTreeMap = BTreeMap::new(); diff --git a/src/test/run-pass/traits-issue-22019.rs b/src/test/run-pass/traits-issue-22019.rs index 5d3195e193708..7e0f60d55a827 100644 --- a/src/test/run-pass/traits-issue-22019.rs +++ b/src/test/run-pass/traits-issue-22019.rs @@ -23,18 +23,18 @@ pub type Node<'a> = &'a CFGNode; pub trait GraphWalk<'c, N> { /// Returns all the nodes in this graph. - fn nodes(&'c self) where [N]:ToOwned>; + fn nodes(&'c self) where [N]:ToOwned>; } impl<'g> GraphWalk<'g, Node<'g>> for u32 { - fn nodes(&'g self) where [Node<'g>]:ToOwned>> + fn nodes(&'g self) where [Node<'g>]:ToOwned>> { loop { } } } impl<'h> GraphWalk<'h, Node<'h>> for u64 { - fn nodes(&'h self) where [Node<'h>]:ToOwned>> + fn nodes(&'h self) where [Node<'h>]:ToOwned>> { loop { } } } From 365bd9a9e3b9dafa98e26982353fd28a6ca1efef Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 18 Feb 2015 14:39:37 -0800 Subject: [PATCH 69/76] Round 1 fixes and rebase conflicts --- src/libcollections/bit.rs | 4 ++-- src/libcore/iter.rs | 10 +++++----- src/libcoretest/hash/mod.rs | 2 -- src/librustc_trans/trans/tvec.rs | 2 +- src/librustdoc/flock.rs | 2 +- src/librustdoc/html/markdown.rs | 4 ++-- src/libstd/collections/hash/map_stage0.rs | 5 +++-- src/libstd/collections/hash/set_stage0.rs | 5 +++-- src/libstd/ffi/c_str.rs | 14 +++++++------- src/test/run-pass/bitv-perf-test.rs | 6 +++--- src/test/run-pass/c-stack-returning-int64.rs | 4 ++-- src/test/run-pass/const-polymorphic-paths.rs | 6 +++--- src/test/run-pass/foreign-fn-linkname.rs | 2 +- src/test/run-pass/issue-11736.rs | 4 ++-- src/test/run-pass/issue-2383.rs | 4 ++-- src/test/run-pass/rename-directory.rs | 6 +++--- src/test/run-pass/variadic-ffi.rs | 8 ++++---- 17 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index d9c2290e68ced..11c576eab1525 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -925,7 +925,7 @@ impl Default for BitVec { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for BitVec { fn from_iter>(iter: I) -> BitVec { - let mut ret = Bitv::new(); + let mut ret = BitVec::new(); ret.extend(iter); ret } @@ -1146,7 +1146,7 @@ impl Default for BitSet { #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for BitSet { fn from_iter>(iter: I) -> BitSet { - let mut ret = BitvSet::new(); + let mut ret = BitSet::new(); ret.extend(iter); ret } diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 7a6c3a0077233..194c0dc4f28ea 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -522,11 +522,11 @@ pub trait IteratorExt: Iterator + Sized { /// /// let a = [1, 4, 2, 3, 8, 9, 6]; /// let sum = a.iter() - /// .cloned() - /// .inspect(|&x| println!("filtering {}", x)) - /// .filter(|&x| x % 2 == 0) - /// .inspect(|&x| println!("{} made it through", x)) - /// .sum(); + /// .map(|x| *x) + /// .inspect(|&x| println!("filtering {}", x)) + /// .filter(|&x| x % 2 == 0) + /// .inspect(|&x| println!("{} made it through", x)) + /// .sum(); /// println!("{}", sum); /// ``` #[inline] diff --git a/src/libcoretest/hash/mod.rs b/src/libcoretest/hash/mod.rs index 2d85769c0cddf..9b6af182f729c 100644 --- a/src/libcoretest/hash/mod.rs +++ b/src/libcoretest/hash/mod.rs @@ -23,7 +23,6 @@ impl Default for MyHasher { } impl Hasher for MyHasher { - type Output = u64; fn write(&mut self, buf: &[u8]) { for byte in buf { self.hash += *byte as u64; @@ -85,7 +84,6 @@ struct Custom { hash: u64 } struct CustomHasher { output: u64 } impl Hasher for CustomHasher { - type Output = u64; fn finish(&self) -> u64 { self.output } fn write(&mut self, data: &[u8]) { panic!() } fn write_u64(&mut self, data: u64) { self.output = data; } diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index 29a5d45a8be3f..7b59e0258ee22 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -426,7 +426,7 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, Br(bcx, loop_bcx.llbb, DebugLoc::None); let loop_counter = Phi(loop_bcx, bcx.ccx().int_type(), - &[C_uint(bcx.ccx(), 0)], &[bcx.llbb]); + &[C_uint(bcx.ccx(), 0 as usize)], &[bcx.llbb]); let bcx = loop_bcx; diff --git a/src/librustdoc/flock.rs b/src/librustdoc/flock.rs index eba915af519c8..ad91c3cb2c35b 100644 --- a/src/librustdoc/flock.rs +++ b/src/librustdoc/flock.rs @@ -112,7 +112,7 @@ mod imp { impl Lock { pub fn new(p: &Path) -> Lock { - let buf = CString::from_slice(p.as_vec()).unwrap(); + let buf = CString::new(p.as_vec()).unwrap(); let fd = unsafe { libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT, libc::S_IRWXU) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 3ceaec5f53d82..7ea5bd569e199 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -236,7 +236,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { s.push_str(&highlight::highlight(&text, None, Some("rust-example-rendered"))); - let output = CString::from_vec(s.into_bytes()).unwrap(); + let output = CString::new(s).unwrap(); hoedown_buffer_puts(ob, output.as_ptr()); }) } @@ -293,7 +293,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { format!("{} ", sec) }); - let text = CString::from_vec(text.into_bytes()).unwrap(); + let text = CString::new(text).unwrap(); unsafe { hoedown_buffer_puts(ob, text.as_ptr()) } } diff --git a/src/libstd/collections/hash/map_stage0.rs b/src/libstd/collections/hash/map_stage0.rs index 18241c7a0c3d8..8ae195cf991d3 100644 --- a/src/libstd/collections/hash/map_stage0.rs +++ b/src/libstd/collections/hash/map_stage0.rs @@ -1552,7 +1552,8 @@ impl FromIterator<(K, V)> for HashMap S: HashState + Default, H: hash::Hasher { - fn from_iter>(iter: T) -> HashMap { + fn from_iter>(iter: T) -> HashMap { + let iter = iter.into_iter(); let lower = iter.size_hint().0; let mut map = HashMap::with_capacity_and_hash_state(lower, Default::default()); @@ -1567,7 +1568,7 @@ impl Extend<(K, V)> for HashMap S: HashState, H: hash::Hasher { - fn extend>(&mut self, iter: T) { + fn extend>(&mut self, iter: T) { for (k, v) in iter { self.insert(k, v); } diff --git a/src/libstd/collections/hash/set_stage0.rs b/src/libstd/collections/hash/set_stage0.rs index 3bc22236a47f2..9d615d0c3ffca 100644 --- a/src/libstd/collections/hash/set_stage0.rs +++ b/src/libstd/collections/hash/set_stage0.rs @@ -622,7 +622,8 @@ impl FromIterator for HashSet S: HashState + Default, H: hash::Hasher { - fn from_iter>(iter: I) -> HashSet { + fn from_iter>(iter: I) -> HashSet { + let iter = iter.into_iter(); let lower = iter.size_hint().0; let mut set = HashSet::with_capacity_and_hash_state(lower, Default::default()); set.extend(iter); @@ -636,7 +637,7 @@ impl Extend for HashSet S: HashState, H: hash::Hasher { - fn extend>(&mut self, iter: I) { + fn extend>(&mut self, iter: I) { for k in iter { self.insert(k); } diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 70c14ef197829..8976813d3f91e 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -105,7 +105,7 @@ pub struct CString { /// } /// /// fn main() { -/// let s = CString::from_slice(b"data data data data").unwrap(); +/// let s = CString::new("data data data data").unwrap(); /// work(&s); /// } /// ``` @@ -141,7 +141,7 @@ impl CString { /// extern { fn puts(s: *const libc::c_char); } /// /// fn main() { - /// let to_print = CString::from_slice(b"Hello!").unwrap(); + /// let to_print = CString::new("Hello!").unwrap(); /// unsafe { /// puts(to_print.as_ptr()); /// } @@ -175,7 +175,7 @@ impl CString { /// extern { fn puts(s: *const libc::c_char); } /// /// fn main() { - /// let to_print = CString::from_slice(b"Hello!").unwrap(); + /// let to_print = CString::new("Hello!").unwrap(); /// unsafe { /// puts(to_print.as_ptr()); /// } @@ -436,18 +436,18 @@ mod tests { #[test] fn simple() { - let s = CString::from_slice(b"1234").unwrap(); + let s = CString::new(b"1234").unwrap(); assert_eq!(s.as_bytes(), b"1234"); assert_eq!(s.as_bytes_with_nul(), b"1234\0"); } #[test] fn build_with_zero1() { - assert!(CString::from_slice(b"\0").is_err()); + assert!(CString::new(b"\0").is_err()); } #[test] fn build_with_zero2() { - assert!(CString::from_vec(vec![0]).is_err()); + assert!(CString::new(vec![0]).is_err()); } #[test] @@ -460,7 +460,7 @@ mod tests { #[test] fn formatted() { - let s = CString::from_slice(b"12").unwrap(); + let s = CString::new(b"12").unwrap(); assert_eq!(format!("{:?}", s), "\"12\""); } diff --git a/src/test/run-pass/bitv-perf-test.rs b/src/test/run-pass/bitv-perf-test.rs index b6d428924e3e9..7bb9f042fe891 100644 --- a/src/test/run-pass/bitv-perf-test.rs +++ b/src/test/run-pass/bitv-perf-test.rs @@ -13,11 +13,11 @@ #![feature(box_syntax)] extern crate collections; -use std::collections::Bitv; +use std::collections::BitVec; fn bitv_test() { - let mut v1 = box Bitv::from_elem(31, false); - let v2 = box Bitv::from_elem(31, true); + let mut v1 = box BitVec::from_elem(31, false); + let v2 = box BitVec::from_elem(31, true); v1.union(&*v2); } diff --git a/src/test/run-pass/c-stack-returning-int64.rs b/src/test/run-pass/c-stack-returning-int64.rs index d18a3055b9c81..6246ee9c6c41a 100644 --- a/src/test/run-pass/c-stack-returning-int64.rs +++ b/src/test/run-pass/c-stack-returning-int64.rs @@ -24,12 +24,12 @@ mod mlibc { } fn atol(s: String) -> int { - let c = CString::from_slice(s.as_bytes()).unwrap(); + let c = CString::new(s).unwrap(); unsafe { mlibc::atol(c.as_ptr()) as int } } fn atoll(s: String) -> i64 { - let c = CString::from_slice(s.as_bytes()).unwrap(); + let c = CString::new(s).unwrap(); unsafe { mlibc::atoll(c.as_ptr()) as i64 } } diff --git a/src/test/run-pass/const-polymorphic-paths.rs b/src/test/run-pass/const-polymorphic-paths.rs index f8f92a56adb1a..e9d10536b75a1 100644 --- a/src/test/run-pass/const-polymorphic-paths.rs +++ b/src/test/run-pass/const-polymorphic-paths.rs @@ -11,7 +11,7 @@ #![feature(macro_rules)] use std::borrow::{Cow, IntoCow}; -use std::collections::Bitv; +use std::collections::BitVec; use std::default::Default; use std::iter::FromIterator; use std::ops::Add; @@ -63,8 +63,8 @@ tests! { Vec::<()>::new, fn() -> Vec<()>, (); Vec::with_capacity, fn(uint) -> Vec<()>, (5); Vec::<()>::with_capacity, fn(uint) -> Vec<()>, (5); - Bitv::from_fn, fn(uint, fn(uint) -> bool) -> Bitv, (5, odd); - Bitv::from_fn:: bool>, fn(uint, fn(uint) -> bool) -> Bitv, (5, odd); + BitVec::from_fn, fn(uint, fn(uint) -> bool) -> BitVec, (5, odd); + BitVec::from_fn:: bool>, fn(uint, fn(uint) -> bool) -> BitVec, (5, odd); // Inherent non-static method. Vec::map_in_place, fn(Vec, fn(u8) -> i8) -> Vec, (vec![b'f', b'o', b'o'], u8_as_i8); diff --git a/src/test/run-pass/foreign-fn-linkname.rs b/src/test/run-pass/foreign-fn-linkname.rs index 69e5b9f43ea62..24b711328a18a 100644 --- a/src/test/run-pass/foreign-fn-linkname.rs +++ b/src/test/run-pass/foreign-fn-linkname.rs @@ -24,7 +24,7 @@ mod mlibc { fn strlen(str: String) -> uint { // C string is terminated with a zero - let s = CString::from_slice(str.as_bytes()).unwrap(); + let s = CString::new(str).unwrap(); unsafe { mlibc::my_strlen(s.as_ptr()) as uint } diff --git a/src/test/run-pass/issue-11736.rs b/src/test/run-pass/issue-11736.rs index d9bae6886fa2e..b901e95ff55ed 100644 --- a/src/test/run-pass/issue-11736.rs +++ b/src/test/run-pass/issue-11736.rs @@ -10,13 +10,13 @@ extern crate collections; -use std::collections::Bitv; +use std::collections::BitVec; use std::num::Float; fn main() { // Generate sieve of Eratosthenes for n up to 1e6 let n = 1000000_usize; - let mut sieve = Bitv::from_elem(n+1, true); + let mut sieve = BitVec::from_elem(n+1, true); let limit: uint = (n as f32).sqrt() as uint; for i in 2..limit+1 { if sieve[i] { diff --git a/src/test/run-pass/issue-2383.rs b/src/test/run-pass/issue-2383.rs index b8136323df664..a5a05283f80fd 100644 --- a/src/test/run-pass/issue-2383.rs +++ b/src/test/run-pass/issue-2383.rs @@ -10,9 +10,9 @@ // except according to those terms. extern crate collections; -use std::collections::RingBuf; +use std::collections::VecDeque; pub fn main() { - let mut q = RingBuf::new(); + let mut q = VecDeque::new(); q.push_front(10); } diff --git a/src/test/run-pass/rename-directory.rs b/src/test/run-pass/rename-directory.rs index 54e0e2de24298..abe6ffe7d4cca 100644 --- a/src/test/run-pass/rename-directory.rs +++ b/src/test/run-pass/rename-directory.rs @@ -31,12 +31,12 @@ fn rename_directory() { let test_file = &old_path.join("temp.txt"); /* Write the temp input file */ - let fromp = CString::from_slice(test_file.as_vec()).unwrap(); - let modebuf = CString::from_slice(b"w+b").unwrap(); + let fromp = CString::new(test_file.as_vec()).unwrap(); + let modebuf = CString::new(b"w+b").unwrap(); let ostream = libc::fopen(fromp.as_ptr(), modebuf.as_ptr()); assert!((ostream as uint != 0_usize)); let s = "hello".to_string(); - let buf = CString::from_slice(b"hello").unwrap(); + let buf = CString::new(b"hello").unwrap(); let write_len = libc::fwrite(buf.as_ptr() as *mut _, 1_usize as libc::size_t, (s.len() + 1_usize) as libc::size_t, diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs index 85f6ef0ddcd1b..5a476ed9ee2f8 100644 --- a/src/test/run-pass/variadic-ffi.rs +++ b/src/test/run-pass/variadic-ffi.rs @@ -29,11 +29,11 @@ pub fn main() { unsafe { // Call with just the named parameter - let c = CString::from_slice(b"Hello World\n").unwrap(); + let c = CString::new(b"Hello World\n").unwrap(); check("Hello World\n", |s| sprintf(s, c.as_ptr())); // Call with variable number of arguments - let c = CString::from_slice(b"%d %f %c %s\n").unwrap(); + let c = CString::new(b"%d %f %c %s\n").unwrap(); check("42 42.500000 a %d %f %c %s\n\n", |s| { sprintf(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr()); }); @@ -44,11 +44,11 @@ pub fn main() { // A function that takes a function pointer unsafe fn call(p: unsafe extern fn(*mut c_char, *const c_char, ...) -> c_int) { // Call with just the named parameter - let c = CString::from_slice(b"Hello World\n").unwrap(); + let c = CString::new(b"Hello World\n").unwrap(); check("Hello World\n", |s| sprintf(s, c.as_ptr())); // Call with variable number of arguments - let c = CString::from_slice(b"%d %f %c %s\n").unwrap(); + let c = CString::new(b"%d %f %c %s\n").unwrap(); check("42 42.500000 a %d %f %c %s\n\n", |s| { sprintf(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr()); }); From 3e7a04cb3cac2b803dc8188d9a55ba1836404ea3 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 18 Feb 2015 15:48:45 -0800 Subject: [PATCH 70/76] Round 2 test fixes and conflicts --- src/libcore/hash/mod.rs | 126 ++++++++++++++++++++-- src/libstd/collections/hash/map_stage0.rs | 26 ++--- src/libstd/collections/hash/set_stage0.rs | 6 +- 3 files changed, 131 insertions(+), 27 deletions(-) diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index 3d0c9761dda77..1bd8aa0a17ecc 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -231,7 +231,6 @@ pub fn hash(value: &T) -> u64 { mod impls { use prelude::*; - use borrow::{Cow, ToOwned}; use mem; use num::Int; use super::*; @@ -364,22 +363,12 @@ mod impls { (*self as uint).hash(state); } } - - impl<'a, T, B: ?Sized, S: Hasher> Hash for Cow<'a, T, B> - where B: Hash + ToOwned - { - #[inline] - fn hash(&self, state: &mut S) { - Hash::hash(&**self, state) - } - } } #[cfg(not(stage0))] mod impls { use prelude::*; - use borrow::{Cow, ToOwned}; use slice; use super::*; @@ -399,4 +388,119 @@ mod impls { } )*} } + + impl_write! { + (u8, write_u8), + (u16, write_u16), + (u32, write_u32), + (u64, write_u64), + (usize, write_usize), + (i8, write_i8), + (i16, write_i16), + (i32, write_i32), + (i64, write_i64), + (isize, write_isize), + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for bool { + fn hash(&self, state: &mut H) { + state.write_u8(*self as u8) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for char { + fn hash(&self, state: &mut H) { + state.write_u32(*self as u32) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for str { + fn hash(&self, state: &mut H) { + state.write(self.as_bytes()); + state.write_u8(0xff) + } + } + + macro_rules! impl_hash_tuple { + () => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for () { + fn hash(&self, _state: &mut H) {} + } + ); + + ( $($name:ident)+) => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($name: Hash),*> Hash for ($($name,)*) { + #[allow(non_snake_case)] + fn hash(&self, state: &mut S) { + let ($(ref $name,)*) = *self; + $($name.hash(state);)* + } + } + ); + } + + impl_hash_tuple! {} + impl_hash_tuple! { A } + impl_hash_tuple! { A B } + impl_hash_tuple! { A B C } + impl_hash_tuple! { A B C D } + impl_hash_tuple! { A B C D E } + impl_hash_tuple! { A B C D E F } + impl_hash_tuple! { A B C D E F G } + impl_hash_tuple! { A B C D E F G H } + impl_hash_tuple! { A B C D E F G H I } + impl_hash_tuple! { A B C D E F G H I J } + impl_hash_tuple! { A B C D E F G H I J K } + impl_hash_tuple! { A B C D E F G H I J K L } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for [T] { + fn hash(&self, state: &mut H) { + self.len().hash(state); + Hash::hash_slice(self, state) + } + } + + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized + Hash> Hash for &'a T { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized + Hash> Hash for &'a mut T { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for *const T { + fn hash(&self, state: &mut H) { + state.write_usize(*self as usize) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for *mut T { + fn hash(&self, state: &mut H) { + state.write_usize(*self as usize) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T, B: ?Sized> Hash for Cow<'a, T, B> + where B: Hash + ToOwned + { + fn hash(&self, state: &mut H) { + Hash::hash(&**self, state) + } + } } diff --git a/src/libstd/collections/hash/map_stage0.rs b/src/libstd/collections/hash/map_stage0.rs index 8ae195cf991d3..f9e5044c59761 100644 --- a/src/libstd/collections/hash/map_stage0.rs +++ b/src/libstd/collections/hash/map_stage0.rs @@ -14,7 +14,7 @@ use self::Entry::*; use self::SearchResult::*; use self::VacantEntryState::*; -use borrow::BorrowFrom; +use borrow::Borrow; use clone::Clone; use cmp::{max, Eq, PartialEq}; use default::Default; @@ -453,18 +453,18 @@ impl HashMap /// If you already have the hash for the key lying around, use /// search_hashed. fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> Option> - where Q: BorrowFrom + Eq + Hash + where K: Borrow, Q: Eq + Hash { let hash = self.make_hash(q); - search_hashed(&self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k))) + search_hashed(&self.table, hash, |k| q.eq(k.borrow())) .into_option() } fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> Option> - where Q: BorrowFrom + Eq + Hash + where K: Borrow, Q: Eq + Hash { let hash = self.make_hash(q); - search_hashed(&mut self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k))) + search_hashed(&mut self.table, hash, |k| q.eq(k.borrow())) .into_option() } @@ -1037,7 +1037,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self, k: &Q) -> Option<&V> - where Q: Hash + Eq + BorrowFrom + where K: Borrow, Q: Hash + Eq { self.search(k).map(|bucket| bucket.into_refs().1) } @@ -1060,7 +1060,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains_key(&self, k: &Q) -> bool - where Q: Hash + Eq + BorrowFrom + where K: Borrow, Q: Hash + Eq { self.search(k).is_some() } @@ -1086,7 +1086,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> - where Q: Hash + Eq + BorrowFrom + where K: Borrow, Q: Hash + Eq { self.search_mut(k).map(|bucket| bucket.into_mut_refs().1) } @@ -1138,7 +1138,7 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, k: &Q) -> Option - where Q: Hash + Eq + BorrowFrom + where K: Borrow, Q: Hash + Eq { if self.table.size() == 0 { return None @@ -1247,8 +1247,8 @@ impl Default for HashMap #[stable(feature = "rust1", since = "1.0.0")] impl Index for HashMap - where K: Eq + Hash, - Q: Eq + Hash + BorrowFrom, + where K: Eq + Hash + Borrow, + Q: Eq + Hash, S: HashState, H: hash::Hasher { @@ -1262,8 +1262,8 @@ impl Index for HashMap #[stable(feature = "rust1", since = "1.0.0")] impl IndexMut for HashMap - where K: Eq + Hash, - Q: Eq + Hash + BorrowFrom, + where K: Eq + Hash + Borrow, + Q: Eq + Hash, S: HashState, H: hash::Hasher { diff --git a/src/libstd/collections/hash/set_stage0.rs b/src/libstd/collections/hash/set_stage0.rs index 9d615d0c3ffca..68c9e02d8ad72 100644 --- a/src/libstd/collections/hash/set_stage0.rs +++ b/src/libstd/collections/hash/set_stage0.rs @@ -10,7 +10,7 @@ // // ignore-lexer-test FIXME #15883 -use borrow::BorrowFrom; +use borrow::Borrow; use clone::Clone; use cmp::{Eq, PartialEq}; use core::marker::Sized; @@ -462,7 +462,7 @@ impl HashSet /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains(&self, value: &Q) -> bool - where Q: BorrowFrom + Hash + Eq + where T: Borrow, Q: Hash + Eq { self.map.contains_key(value) } @@ -572,7 +572,7 @@ impl HashSet /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, value: &Q) -> bool - where Q: BorrowFrom + Hash + Eq + where T: Borrow, Q: Hash + Eq { self.map.remove(value).is_some() } From d6e939a2df16338e9cf63ad19d1025a15069387c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 18 Feb 2015 15:58:07 -0800 Subject: [PATCH 71/76] Round 3 test fixes and conflicts --- src/libcore/array.rs | 2 +- src/libcore/hash/mod.rs | 9 -- src/libcore/marker.rs | 7 ++ src/libgraphviz/lib.rs | 19 ++-- src/libsyntax/diagnostic.rs | 10 +- src/libsyntax/ext/source_util.rs | 8 +- src/libsyntax/ext/tt/macro_parser.rs | 6 +- src/libsyntax/ext/tt/macro_rules.rs | 6 +- src/libsyntax/ext/tt/transcribe.rs | 2 +- src/libsyntax/parse/lexer/mod.rs | 5 +- src/libsyntax/parse/parser.rs | 46 ++++---- src/libsyntax/print/pp.rs | 4 +- src/libsyntax/print/pprust.rs | 102 +++++++++--------- src/libsyntax/test.rs | 2 +- src/libsyntax/util/interner.rs | 4 +- src/test/compile-fail/cross-borrow-trait.rs | 2 +- .../compile-fail/destructure-trait-ref.rs | 2 +- src/test/compile-fail/dst-bad-coerce1.rs | 2 +- src/test/compile-fail/dst-bad-coerce3.rs | 2 +- .../dst-object-from-unsized-type.rs | 2 +- src/test/compile-fail/issue-5543.rs | 4 +- .../kindck-inherited-copy-bound.rs | 1 + .../regions-close-object-into-object-5.rs | 4 +- .../regions-close-param-into-object.rs | 2 +- src/test/run-pass/borrowck-trait-lifetime.rs | 2 +- src/test/run-pass/issue-14399.rs | 2 +- src/test/run-pass/trait-impl.rs | 3 +- src/test/run-pass/unique-object-move.rs | 2 +- 28 files changed, 127 insertions(+), 135 deletions(-) diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 0c563f60c13ba..afb5d95c9f8d7 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -45,7 +45,7 @@ macro_rules! array_impls { #[stable(feature = "rust1", since = "1.0.0")] impl Hash for [T; $N] { fn hash(&self, state: &mut H) { - Hash::hash(&self[], state) + Hash::hash(&self[..], state) } } diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index 1bd8aa0a17ecc..1086ae84ded6d 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -494,13 +494,4 @@ mod impls { state.write_usize(*self as usize) } } - - #[stable(feature = "rust1", since = "1.0.0")] - impl<'a, T, B: ?Sized> Hash for Cow<'a, T, B> - where B: Hash + ToOwned - { - fn hash(&self, state: &mut H) { - Hash::hash(&**self, state) - } - } } diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index dc792a3f47f60..dbe6db86adab5 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -233,11 +233,18 @@ pub struct Managed; macro_rules! impls{ ($t: ident) => ( + #[cfg(stage0)] impl Hash for $t { #[inline] fn hash(&self, _: &mut S) { } } + #[cfg(not(stage0))] + impl Hash for $t { + #[inline] + fn hash(&self, _: &mut H) { + } + } impl cmp::PartialEq for $t { fn eq(&self, _other: &$t) -> bool { diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 3d594378f5586..acd52c752e8aa 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -275,15 +275,12 @@ html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(int_uint)] #![feature(collections)] -#![feature(core)] #![feature(old_io)] use self::LabelText::*; -use std::borrow::IntoCow; +use std::borrow::{IntoCow, Cow}; use std::old_io; -use std::string::CowString; -use std::vec::CowVec; /// The text for a graphviz label on a node or edge. pub enum LabelText<'a> { @@ -291,7 +288,7 @@ pub enum LabelText<'a> { /// /// Occurrences of backslashes (`\`) are escaped, and thus appear /// as backslashes in the rendered label. - LabelStr(CowString<'a>), + LabelStr(Cow<'a, str>), /// This kind of label uses the graphviz label escString type: /// http://www.graphviz.org/content/attrs#kescString @@ -303,7 +300,7 @@ pub enum LabelText<'a> { /// to break a line (centering the line preceding the `\n`), there /// are also the escape sequences `\l` which left-justifies the /// preceding line and `\r` which right-justifies it. - EscStr(CowString<'a>), + EscStr(Cow<'a, str>), } // There is a tension in the design of the labelling API. @@ -340,7 +337,7 @@ pub enum LabelText<'a> { /// `Id` is a Graphviz `ID`. pub struct Id<'a> { - name: CowString<'a>, + name: Cow<'a, str>, } impl<'a> Id<'a> { @@ -387,7 +384,7 @@ impl<'a> Id<'a> { &*self.name } - pub fn name(self) -> CowString<'a> { + pub fn name(self) -> Cow<'a, str> { self.name } } @@ -463,7 +460,7 @@ impl<'a> LabelText<'a> { /// yields same content as self. The result obeys the law /// render(`lt`) == render(`EscStr(lt.pre_escaped_content())`) for /// all `lt: LabelText`. - fn pre_escaped_content(self) -> CowString<'a> { + fn pre_escaped_content(self) -> Cow<'a, str> { match self { EscStr(s) => s, LabelStr(s) => if s.contains_char('\\') { @@ -489,8 +486,8 @@ impl<'a> LabelText<'a> { } } -pub type Nodes<'a,N> = CowVec<'a,N>; -pub type Edges<'a,E> = CowVec<'a,E>; +pub type Nodes<'a,N> = Cow<'a,[N]>; +pub type Edges<'a,E> = Cow<'a,[E]>; // (The type parameters in GraphWalk should be associated items, // when/if Rust supports such.) diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 02643fae9a167..27219774cf148 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -311,16 +311,16 @@ fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level, } try!(print_maybe_styled(dst, - &format!("{}: ", lvl.to_string())[], + &format!("{}: ", lvl.to_string()), term::attr::ForegroundColor(lvl.color()))); try!(print_maybe_styled(dst, - &format!("{}", msg)[], + &format!("{}", msg), term::attr::Bold)); match code { Some(code) => { let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA); - try!(print_maybe_styled(dst, &format!(" [{}]", code.clone())[], style)); + try!(print_maybe_styled(dst, &format!(" [{}]", code.clone()), style)); } None => () } @@ -438,7 +438,7 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan, Some(_) => { try!(print_diagnostic(dst, &ss[..], Help, &format!("pass `--explain {}` to see a detailed \ - explanation", code)[], None)); + explanation", code), None)); } None => () }, @@ -542,7 +542,7 @@ fn highlight_lines(err: &mut EmitterWriter, } try!(print_maybe_styled(err, - &format!("{}\n", s)[], + &format!("{}\n", s), term::attr::ForegroundColor(lvl.color()))); } } diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 22fac22c9cc52..c8d48750c7509 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -117,7 +117,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree None => self.p.span_fatal( self.p.span, &format!("expected item, found `{}`", - self.p.this_token_to_string())[] + self.p.this_token_to_string()) ) } } @@ -141,7 +141,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), - e)[]); + e)); return DummyResult::expr(sp); } Ok(bytes) => bytes, @@ -159,7 +159,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) Err(_) => { cx.span_err(sp, &format!("{} wasn't a utf-8 file", - file.display())[]); + file.display())); return DummyResult::expr(sp); } } @@ -175,7 +175,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) match File::open(&file).read_to_end() { Err(e) => { cx.span_err(sp, - &format!("couldn't read {}: {}", file.display(), e)[]); + &format!("couldn't read {}: {}", file.display(), e)); return DummyResult::expr(sp); } Ok(bytes) => { diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index dca734e1f5e89..664f7b3e08848 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -229,7 +229,7 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc]) p_s.span_diagnostic .span_fatal(sp, &format!("duplicated bind name: {}", - &string)[]) + &string)) } } } @@ -533,7 +533,7 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal { _ => { let token_str = pprust::token_to_string(&p.token); p.fatal(&format!("expected ident, found {}", - &token_str[..])[]) + &token_str[..])) } }, "path" => { @@ -542,7 +542,7 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal { "meta" => token::NtMeta(p.parse_meta_item()), _ => { p.span_fatal_help(sp, - &format!("invalid fragment specifier `{}`", name)[], + &format!("invalid fragment specifier `{}`", name), "valid fragment specifiers are `ident`, `block`, \ `stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \ and `item`") diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 624cb9ddf4256..fa6d934a45755 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -123,8 +123,8 @@ impl TTMacroExpander for MacroRulesMacroExpander { self.name, self.imported_from, arg, - &self.lhses[], - &self.rhses[]) + &self.lhses, + &self.rhses) } } @@ -151,7 +151,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, match **lhs { MatchedNonterminal(NtTT(ref lhs_tt)) => { let lhs_tt = match **lhs_tt { - TtDelimited(_, ref delim) => &delim.tts[], + TtDelimited(_, ref delim) => &delim.tts[..], _ => cx.span_fatal(sp, "malformed macro lhs") }; // `None` is because we're not interpolating diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 17016f3ac1179..0d92bd761b418 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -309,7 +309,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { r.sp_diag.span_fatal( r.cur_span, /* blame the macro writer */ &format!("variable '{:?}' is still repeating at this depth", - token::get_ident(ident))[]); + token::get_ident(ident))); } } } diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index cca641a7852f4..fd08cbd161bfe 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -16,14 +16,13 @@ use ext::tt::transcribe::tt_next_token; use parse::token; use parse::token::{str_to_ident}; -use std::borrow::IntoCow; +use std::borrow::{IntoCow, Cow}; use std::char; use std::fmt; use std::mem::replace; use std::num; use std::rc::Rc; use std::str; -use std::string::CowString; pub use ext::tt::transcribe::{TtReader, new_tt_reader, new_tt_reader_with_doc_flag}; @@ -278,7 +277,7 @@ impl<'a> StringReader<'a> { /// Converts CRLF to LF in the given string, raising an error on bare CR. fn translate_crlf<'b>(&self, start: BytePos, - s: &'b str, errmsg: &'b str) -> CowString<'b> { + s: &'b str, errmsg: &'b str) -> Cow<'b, str> { let mut i = 0; while i < s.len() { let str::CharRange { ch, next } = s.char_range_at(i); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e272c770cb7a3..370201e53825e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4401,7 +4401,7 @@ impl<'a> Parser<'a> { _ => { let token_str = self.this_token_to_string(); self.fatal(&format!("expected `Self`, found `{}`", - token_str)[]) + token_str)) } } } @@ -4536,7 +4536,7 @@ impl<'a> Parser<'a> { _ => { let token_str = self.this_token_to_string(); self.fatal(&format!("expected `,` or `)`, found `{}`", - token_str)[]) + token_str)) } } } @@ -4939,7 +4939,7 @@ impl<'a> Parser<'a> { if fields.len() == 0 { self.fatal(&format!("unit-like struct definition should be \ written as `struct {};`", - token::get_ident(class_name.clone()))[]); + token::get_ident(class_name.clone()))); } self.bump(); @@ -4947,7 +4947,7 @@ impl<'a> Parser<'a> { let token_str = self.this_token_to_string(); self.fatal(&format!("expected `where`, or `{}` after struct \ name, found `{}`", "{", - token_str)[]); + token_str)); } fields @@ -4978,7 +4978,7 @@ impl<'a> Parser<'a> { if fields.len() == 0 { self.fatal(&format!("unit-like struct definition should be \ written as `struct {};`", - token::get_ident(class_name.clone()))[]); + token::get_ident(class_name.clone()))); } self.parse_where_clause(generics); @@ -4993,7 +4993,7 @@ impl<'a> Parser<'a> { } else { let token_str = self.this_token_to_string(); self.fatal(&format!("expected `where`, `{}`, `(`, or `;` after struct \ - name, found `{}`", "{", token_str)[]); + name, found `{}`", "{", token_str)); } } @@ -5013,7 +5013,7 @@ impl<'a> Parser<'a> { let token_str = self.this_token_to_string(); self.span_fatal_help(span, &format!("expected `,`, or `}}`, found `{}`", - token_str)[], + token_str), "struct fields should be separated by commas") } } @@ -5085,7 +5085,7 @@ impl<'a> Parser<'a> { // Parse all of the items up to closing or an attribute. let mut attrs = first_item_attrs; - attrs.push_all(&self.parse_outer_attributes()[]); + attrs.push_all(&self.parse_outer_attributes()); let mut items = vec![]; loop { @@ -5105,14 +5105,14 @@ impl<'a> Parser<'a> { while self.token != term { let mut attrs = mem::replace(&mut attrs, vec![]); - attrs.push_all(&self.parse_outer_attributes()[]); + attrs.push_all(&self.parse_outer_attributes()); debug!("parse_mod_items: parse_item_(attrs={:?})", attrs); match self.parse_item_(attrs, true /* macros allowed */) { Ok(item) => items.push(item), Err(_) => { let token_str = self.this_token_to_string(); self.fatal(&format!("expected item, found `{}`", - token_str)[]) + token_str)) } } } @@ -5216,13 +5216,13 @@ impl<'a> Parser<'a> { &format!("maybe move this module `{0}` \ to its own directory via \ `{0}/mod.rs`", - this_module)[]); + this_module)); if default_exists || secondary_exists { self.span_note(id_sp, &format!("... or maybe `use` the module \ `{}` instead of possibly \ redeclaring it", - mod_name)[]); + mod_name)); } self.abort_if_errors(); } @@ -5233,12 +5233,12 @@ impl<'a> Parser<'a> { (false, false) => { self.span_fatal_help(id_sp, &format!("file not found for module `{}`", - mod_name)[], + mod_name), &format!("name the file either {} or {} inside \ the directory {:?}", default_path_str, secondary_path_str, - dir_path.display())[]); + dir_path.display())); } (true, true) => { self.span_fatal_help( @@ -5247,7 +5247,7 @@ impl<'a> Parser<'a> { and {}", mod_name, default_path_str, - secondary_path_str)[], + secondary_path_str), "delete or rename one of them to remove the ambiguity"); } } @@ -5269,10 +5269,10 @@ impl<'a> Parser<'a> { let mut err = String::from_str("circular modules: "); let len = included_mod_stack.len(); for p in &included_mod_stack[i.. len] { - err.push_str(&p.display().as_cow()[]); + err.push_str(&p.display().as_cow()); err.push_str(" -> "); } - err.push_str(&path.display().as_cow()[]); + err.push_str(&path.display().as_cow()); self.span_fatal(id_sp, &err[..]); } None => () @@ -5378,7 +5378,7 @@ impl<'a> Parser<'a> { self.span_help(span, &format!("perhaps you meant to enclose the crate name `{}` in \ a string?", - the_ident.as_str())[]); + the_ident.as_str())); None } else { None @@ -5404,7 +5404,7 @@ impl<'a> Parser<'a> { self.span_fatal(span, &format!("expected extern crate name but \ found `{}`", - token_str)[]); + token_str)); } }; @@ -5502,7 +5502,7 @@ impl<'a> Parser<'a> { self.span_err(start_span, &format!("unit-like struct variant should be written \ without braces, as `{},`", - token::get_ident(ident))[]); + token::get_ident(ident))); } kind = StructVariantKind(struct_def); } else if self.check(&token::OpenDelim(token::Paren)) { @@ -5580,7 +5580,7 @@ impl<'a> Parser<'a> { &format!("illegal ABI: expected one of [{}], \ found `{}`", abi::all_names().connect(", "), - the_string)[]); + the_string)); None } } @@ -5660,7 +5660,7 @@ impl<'a> Parser<'a> { let token_str = self.this_token_to_string(); self.span_fatal(span, &format!("expected `{}` or `fn`, found `{}`", "{", - token_str)[]); + token_str)); } if self.eat_keyword_noexpect(keywords::Virtual) { @@ -6054,7 +6054,7 @@ impl<'a> Parser<'a> { fn parse_foreign_items(&mut self, first_item_attrs: Vec) -> Vec> { let mut attrs = first_item_attrs; - attrs.push_all(&self.parse_outer_attributes()[]); + attrs.push_all(&self.parse_outer_attributes()); let mut foreign_items = Vec::new(); loop { match self.parse_foreign_item(attrs) { diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 360178ac7281b..1593bfb97fe1d 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -539,8 +539,8 @@ impl Printer { pub fn print(&mut self, token: Token, l: isize) -> old_io::IoResult<()> { debug!("print {} {} (remaining line space={})", tok_str(&token), l, self.space); - debug!("{}", buf_str(&self.token[], - &self.size[], + debug!("{}", buf_str(&self.token, + &self.size, self.left, self.right, 6)); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index e2c7e992675dc..f26578e740120 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -134,7 +134,7 @@ pub fn print_crate<'a>(cm: &'a CodeMap, try!(s.print_attribute(&fake_attr)); } - try!(s.print_mod(&krate.module, &krate.attrs[])); + try!(s.print_mod(&krate.module, &krate.attrs)); try!(s.print_remaining_comments()); eof(&mut s.s) } @@ -765,7 +765,7 @@ impl<'a> State<'a> { item: &ast::ForeignItem) -> IoResult<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(item.span.lo)); - try!(self.print_outer_attributes(&item.attrs[])); + try!(self.print_outer_attributes(&item.attrs)); match item.node { ast::ForeignItemFn(ref decl, ref generics) => { try!(self.print_fn(&**decl, None, abi::Rust, item.ident, generics, @@ -776,7 +776,7 @@ impl<'a> State<'a> { } ast::ForeignItemStatic(ref t, m) => { try!(self.head(&visibility_qualified(item.vis, - "static")[])); + "static"))); if m { try!(self.word_space("mut")); } @@ -793,7 +793,7 @@ impl<'a> State<'a> { fn print_associated_type(&mut self, typedef: &ast::AssociatedType) -> IoResult<()> { - try!(self.print_outer_attributes(&typedef.attrs[])); + try!(self.print_outer_attributes(&typedef.attrs)); try!(self.word_space("type")); try!(self.print_ty_param(&typedef.ty_param)); word(&mut self.s, ";") @@ -812,12 +812,12 @@ impl<'a> State<'a> { pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(item.span.lo)); - try!(self.print_outer_attributes(&item.attrs[])); + try!(self.print_outer_attributes(&item.attrs)); try!(self.ann.pre(self, NodeItem(item))); match item.node { ast::ItemExternCrate(ref optional_path) => { try!(self.head(&visibility_qualified(item.vis, - "extern crate")[])); + "extern crate"))); if let Some((ref p, style)) = *optional_path { try!(self.print_string(p, style)); try!(space(&mut self.s)); @@ -831,7 +831,7 @@ impl<'a> State<'a> { } ast::ItemUse(ref vp) => { try!(self.head(&visibility_qualified(item.vis, - "use")[])); + "use"))); try!(self.print_view_path(&**vp)); try!(word(&mut self.s, ";")); try!(self.end()); // end inner head-block @@ -839,7 +839,7 @@ impl<'a> State<'a> { } ast::ItemStatic(ref ty, m, ref expr) => { try!(self.head(&visibility_qualified(item.vis, - "static")[])); + "static"))); if m == ast::MutMutable { try!(self.word_space("mut")); } @@ -856,7 +856,7 @@ impl<'a> State<'a> { } ast::ItemConst(ref ty, ref expr) => { try!(self.head(&visibility_qualified(item.vis, - "const")[])); + "const"))); try!(self.print_ident(item.ident)); try!(self.word_space(":")); try!(self.print_type(&**ty)); @@ -879,28 +879,28 @@ impl<'a> State<'a> { item.vis )); try!(word(&mut self.s, " ")); - try!(self.print_block_with_attrs(&**body, &item.attrs[])); + try!(self.print_block_with_attrs(&**body, &item.attrs)); } ast::ItemMod(ref _mod) => { try!(self.head(&visibility_qualified(item.vis, - "mod")[])); + "mod"))); try!(self.print_ident(item.ident)); try!(self.nbsp()); try!(self.bopen()); - try!(self.print_mod(_mod, &item.attrs[])); + try!(self.print_mod(_mod, &item.attrs)); try!(self.bclose(item.span)); } ast::ItemForeignMod(ref nmod) => { try!(self.head("extern")); - try!(self.word_nbsp(&nmod.abi.to_string()[])); + try!(self.word_nbsp(&nmod.abi.to_string())); try!(self.bopen()); - try!(self.print_foreign_mod(nmod, &item.attrs[])); + try!(self.print_foreign_mod(nmod, &item.attrs)); try!(self.bclose(item.span)); } ast::ItemTy(ref ty, ref params) => { try!(self.ibox(indent_unit)); try!(self.ibox(0)); - try!(self.word_nbsp(&visibility_qualified(item.vis, "type")[])); + try!(self.word_nbsp(&visibility_qualified(item.vis, "type"))); try!(self.print_ident(item.ident)); try!(self.print_generics(params)); try!(self.end()); // end the inner ibox @@ -922,7 +922,7 @@ impl<'a> State<'a> { )); } ast::ItemStruct(ref struct_def, ref generics) => { - try!(self.head(&visibility_qualified(item.vis,"struct")[])); + try!(self.head(&visibility_qualified(item.vis,"struct"))); try!(self.print_struct(&**struct_def, generics, item.ident, item.span)); } @@ -963,7 +963,7 @@ impl<'a> State<'a> { try!(space(&mut self.s)); try!(self.bopen()); - try!(self.print_inner_attributes(&item.attrs[])); + try!(self.print_inner_attributes(&item.attrs)); for impl_item in impl_items { match *impl_item { ast::MethodImplItem(ref meth) => { @@ -1049,12 +1049,12 @@ impl<'a> State<'a> { generics: &ast::Generics, ident: ast::Ident, span: codemap::Span, visibility: ast::Visibility) -> IoResult<()> { - try!(self.head(&visibility_qualified(visibility, "enum")[])); + try!(self.head(&visibility_qualified(visibility, "enum"))); try!(self.print_ident(ident)); try!(self.print_generics(generics)); try!(self.print_where_clause(generics)); try!(space(&mut self.s)); - self.print_variants(&enum_definition.variants[], span) + self.print_variants(&enum_definition.variants, span) } pub fn print_variants(&mut self, @@ -1064,7 +1064,7 @@ impl<'a> State<'a> { for v in variants { try!(self.space_if_not_bol()); try!(self.maybe_print_comment(v.span.lo)); - try!(self.print_outer_attributes(&v.node.attrs[])); + try!(self.print_outer_attributes(&v.node.attrs)); try!(self.ibox(indent_unit)); try!(self.print_variant(&**v)); try!(word(&mut self.s, ",")); @@ -1092,7 +1092,7 @@ impl<'a> State<'a> { if !struct_def.fields.is_empty() { try!(self.popen()); try!(self.commasep( - Inconsistent, &struct_def.fields[], + Inconsistent, &struct_def.fields, |s, field| { match field.node.kind { ast::NamedField(..) => panic!("unexpected named field"), @@ -1122,7 +1122,7 @@ impl<'a> State<'a> { ast::NamedField(ident, visibility) => { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(field.span.lo)); - try!(self.print_outer_attributes(&field.node.attrs[])); + try!(self.print_outer_attributes(&field.node.attrs)); try!(self.print_visibility(visibility)); try!(self.print_ident(ident)); try!(self.word_nbsp(":")); @@ -1146,7 +1146,7 @@ impl<'a> State<'a> { pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> { match *tt { ast::TtToken(_, ref tk) => { - try!(word(&mut self.s, &token_to_string(tk)[])); + try!(word(&mut self.s, &token_to_string(tk))); match *tk { parse::token::DocComment(..) => { hardbreak(&mut self.s) @@ -1155,11 +1155,11 @@ impl<'a> State<'a> { } } ast::TtDelimited(_, ref delimed) => { - try!(word(&mut self.s, &token_to_string(&delimed.open_token())[])); + try!(word(&mut self.s, &token_to_string(&delimed.open_token()))); try!(space(&mut self.s)); - try!(self.print_tts(&delimed.tts[])); + try!(self.print_tts(&delimed.tts)); try!(space(&mut self.s)); - word(&mut self.s, &token_to_string(&delimed.close_token())[]) + word(&mut self.s, &token_to_string(&delimed.close_token())) }, ast::TtSequence(_, ref seq) => { try!(word(&mut self.s, "$(")); @@ -1169,7 +1169,7 @@ impl<'a> State<'a> { try!(word(&mut self.s, ")")); match seq.separator { Some(ref tk) => { - try!(word(&mut self.s, &token_to_string(tk)[])); + try!(word(&mut self.s, &token_to_string(tk))); } None => {}, } @@ -1233,7 +1233,7 @@ impl<'a> State<'a> { pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> IoResult<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(m.span.lo)); - try!(self.print_outer_attributes(&m.attrs[])); + try!(self.print_outer_attributes(&m.attrs)); try!(self.print_ty_fn(m.abi, m.unsafety, &*m.decl, @@ -1262,7 +1262,7 @@ impl<'a> State<'a> { pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(meth.span.lo)); - try!(self.print_outer_attributes(&meth.attrs[])); + try!(self.print_outer_attributes(&meth.attrs)); match meth.node { ast::MethDecl(ident, ref generics, @@ -1280,7 +1280,7 @@ impl<'a> State<'a> { Some(&explicit_self.node), vis)); try!(word(&mut self.s, " ")); - self.print_block_with_attrs(&**body, &meth.attrs[]) + self.print_block_with_attrs(&**body, &meth.attrs) }, ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _), ..}) => { @@ -1874,11 +1874,11 @@ impl<'a> State<'a> { try!(self.print_string(&a.asm, a.asm_str_style)); try!(self.word_space(":")); - try!(self.commasep(Inconsistent, &a.outputs[], + try!(self.commasep(Inconsistent, &a.outputs, |s, &(ref co, ref o, is_rw)| { match co.slice_shift_char() { Some(('=', operand)) if is_rw => { - try!(s.print_string(&format!("+{}", operand)[], + try!(s.print_string(&format!("+{}", operand), ast::CookedStr)) } _ => try!(s.print_string(&co, ast::CookedStr)) @@ -1891,7 +1891,7 @@ impl<'a> State<'a> { try!(space(&mut self.s)); try!(self.word_space(":")); - try!(self.commasep(Inconsistent, &a.inputs[], + try!(self.commasep(Inconsistent, &a.inputs, |s, &(ref co, ref o)| { try!(s.print_string(&co, ast::CookedStr)); try!(s.popen()); @@ -1902,7 +1902,7 @@ impl<'a> State<'a> { try!(space(&mut self.s)); try!(self.word_space(":")); - try!(self.commasep(Inconsistent, &a.clobbers[], + try!(self.commasep(Inconsistent, &a.clobbers, |s, co| { try!(s.print_string(&co, ast::CookedStr)); Ok(()) @@ -1984,7 +1984,7 @@ impl<'a> State<'a> { } pub fn print_usize(&mut self, i: usize) -> IoResult<()> { - word(&mut self.s, &i.to_string()[]) + word(&mut self.s, &i.to_string()) } pub fn print_name(&mut self, name: ast::Name) -> IoResult<()> { @@ -2074,7 +2074,7 @@ impl<'a> State<'a> { } try!(self.commasep( Inconsistent, - &data.types[], + &data.types, |s, ty| s.print_type(&**ty))); comma = true; } @@ -2097,7 +2097,7 @@ impl<'a> State<'a> { try!(word(&mut self.s, "(")); try!(self.commasep( Inconsistent, - &data.inputs[], + &data.inputs, |s, ty| s.print_type(&**ty))); try!(word(&mut self.s, ")")); @@ -2242,7 +2242,7 @@ impl<'a> State<'a> { } try!(self.cbox(indent_unit)); try!(self.ibox(0)); - try!(self.print_outer_attributes(&arm.attrs[])); + try!(self.print_outer_attributes(&arm.attrs)); let mut first = true; for p in &arm.pats { if first { @@ -2491,7 +2491,7 @@ impl<'a> State<'a> { pub fn print_ty_param(&mut self, param: &ast::TyParam) -> IoResult<()> { try!(self.print_ident(param.ident)); - try!(self.print_bounds(":", ¶m.bounds[])); + try!(self.print_bounds(":", ¶m.bounds)); match param.default { Some(ref default) => { try!(space(&mut self.s)); @@ -2752,7 +2752,7 @@ impl<'a> State<'a> { try!(self.maybe_print_comment(lit.span.lo)); match self.next_lit(lit.span.lo) { Some(ref ltrl) => { - return word(&mut self.s, &(*ltrl).lit[]); + return word(&mut self.s, &(*ltrl).lit); } _ => () } @@ -2774,21 +2774,21 @@ impl<'a> State<'a> { match t { ast::SignedIntLit(st, ast::Plus) => { word(&mut self.s, - &ast_util::int_ty_to_string(st, Some(i as i64))[]) + &ast_util::int_ty_to_string(st, Some(i as i64))) } ast::SignedIntLit(st, ast::Minus) => { let istr = ast_util::int_ty_to_string(st, Some(-(i as i64))); word(&mut self.s, - &format!("-{}", istr)[]) + &format!("-{}", istr)) } ast::UnsignedIntLit(ut) => { word(&mut self.s, &ast_util::uint_ty_to_string(ut, Some(i))) } ast::UnsuffixedIntLit(ast::Plus) => { - word(&mut self.s, &format!("{}", i)[]) + word(&mut self.s, &format!("{}", i)) } ast::UnsuffixedIntLit(ast::Minus) => { - word(&mut self.s, &format!("-{}", i)[]) + word(&mut self.s, &format!("-{}", i)) } } } @@ -2797,7 +2797,7 @@ impl<'a> State<'a> { &format!( "{}{}", &f, - &ast_util::float_ty_to_string(t)[])[]) + &ast_util::float_ty_to_string(t))) } ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, &f[..]), ast::LitBool(val) => { @@ -2809,7 +2809,7 @@ impl<'a> State<'a> { escaped.extend(ascii::escape_default(ch as u8) .map(|c| c as char)); } - word(&mut self.s, &format!("b\"{}\"", escaped)[]) + word(&mut self.s, &format!("b\"{}\"", escaped)) } } } @@ -2850,7 +2850,7 @@ impl<'a> State<'a> { comments::Mixed => { assert_eq!(cmnt.lines.len(), 1); try!(zerobreak(&mut self.s)); - try!(word(&mut self.s, &cmnt.lines[0][])); + try!(word(&mut self.s, &cmnt.lines[0])); zerobreak(&mut self.s) } comments::Isolated => { @@ -2868,7 +2868,7 @@ impl<'a> State<'a> { comments::Trailing => { try!(word(&mut self.s, " ")); if cmnt.lines.len() == 1 { - try!(word(&mut self.s, &cmnt.lines[0][])); + try!(word(&mut self.s, &cmnt.lines[0])); hardbreak(&mut self.s) } else { try!(self.ibox(0)); @@ -2938,7 +2938,7 @@ impl<'a> State<'a> { Some(abi::Rust) => Ok(()), Some(abi) => { try!(self.word_nbsp("extern")); - self.word_nbsp(&abi.to_string()[]) + self.word_nbsp(&abi.to_string()) } None => Ok(()) } @@ -2949,7 +2949,7 @@ impl<'a> State<'a> { match opt_abi { Some(abi) => { try!(self.word_nbsp("extern")); - self.word_nbsp(&abi.to_string()[]) + self.word_nbsp(&abi.to_string()) } None => Ok(()) } @@ -2964,7 +2964,7 @@ impl<'a> State<'a> { if abi != abi::Rust { try!(self.word_nbsp("extern")); - try!(self.word_nbsp(&abi.to_string()[])); + try!(self.word_nbsp(&abi.to_string())); } word(&mut self.s, "fn") diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 31b264eb76d67..7b1fc91e45b5b 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -119,7 +119,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { self.cx.path.push(ident); } debug!("current path: {}", - ast_util::path_name_i(&self.cx.path[])); + ast_util::path_name_i(&self.cx.path)); if is_test_fn(&self.cx, &*i) || is_bench_fn(&self.cx, &*i) { match i.node { diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index bd9a6d7c4feab..dffeac6f3f793 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -144,7 +144,7 @@ impl Interner { } pub fn find(&self, val: &Q) -> Option - where Q: BorrowFrom + Eq + Hash { + where T: Borrow, Q: Eq + Hash { let map = self.map.borrow(); match (*map).get(val) { Some(v) => Some(*v), @@ -285,7 +285,7 @@ impl StrInterner { } #[cfg(not(stage0))] pub fn find(&self, val: &Q) -> Option - where Q: BorrowFrom + Eq + Hash { + where RcStr: Borrow, Q: Eq + Hash { match (*self.map.borrow()).get(val) { Some(v) => Some(*v), None => None, diff --git a/src/test/compile-fail/cross-borrow-trait.rs b/src/test/compile-fail/cross-borrow-trait.rs index c97a9950d78d0..6bd21101a609d 100644 --- a/src/test/compile-fail/cross-borrow-trait.rs +++ b/src/test/compile-fail/cross-borrow-trait.rs @@ -14,7 +14,7 @@ #![feature(box_syntax)] struct Foo; -trait Trait : ::std::marker::MarkerTrait {} +trait Trait { fn foo(&self) {} } impl Trait for Foo {} pub fn main() { diff --git a/src/test/compile-fail/destructure-trait-ref.rs b/src/test/compile-fail/destructure-trait-ref.rs index d8b3f297a1123..4161cce2843b6 100644 --- a/src/test/compile-fail/destructure-trait-ref.rs +++ b/src/test/compile-fail/destructure-trait-ref.rs @@ -14,7 +14,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] -trait T : ::std::marker::MarkerTrait {} +trait T { fn foo(&self) {} } impl T for isize {} fn main() { diff --git a/src/test/compile-fail/dst-bad-coerce1.rs b/src/test/compile-fail/dst-bad-coerce1.rs index 6d9ba8d44c089..ddc929017718d 100644 --- a/src/test/compile-fail/dst-bad-coerce1.rs +++ b/src/test/compile-fail/dst-bad-coerce1.rs @@ -15,7 +15,7 @@ struct Fat { } struct Foo; -trait Bar : ::std::marker::MarkerTrait {} +trait Bar { fn bar(&self) {} } pub fn main() { // With a vec of isize. diff --git a/src/test/compile-fail/dst-bad-coerce3.rs b/src/test/compile-fail/dst-bad-coerce3.rs index 46b89e1122a2c..7bad3bd69d3b0 100644 --- a/src/test/compile-fail/dst-bad-coerce3.rs +++ b/src/test/compile-fail/dst-bad-coerce3.rs @@ -15,7 +15,7 @@ struct Fat { } struct Foo; -trait Bar : ::std::marker::MarkerTrait {} +trait Bar { fn bar(&self) {} } impl Bar for Foo {} fn baz<'a>() { diff --git a/src/test/compile-fail/dst-object-from-unsized-type.rs b/src/test/compile-fail/dst-object-from-unsized-type.rs index a1f0dda671e7d..b4fd45845f7a0 100644 --- a/src/test/compile-fail/dst-object-from-unsized-type.rs +++ b/src/test/compile-fail/dst-object-from-unsized-type.rs @@ -10,7 +10,7 @@ // Test that we cannot create objects from unsized types. -trait Foo : ::std::marker::MarkerTrait {} +trait Foo { fn foo(&self) {} } impl Foo for str {} fn test1(t: &T) { diff --git a/src/test/compile-fail/issue-5543.rs b/src/test/compile-fail/issue-5543.rs index eccbc7896605e..4d721ad76666d 100644 --- a/src/test/compile-fail/issue-5543.rs +++ b/src/test/compile-fail/issue-5543.rs @@ -10,9 +10,7 @@ #![feature(box_syntax)] -use std::marker::MarkerTrait; - -trait Foo : MarkerTrait {} +trait Foo { fn foo(&self) {} } impl Foo for u8 {} fn main() { diff --git a/src/test/compile-fail/kindck-inherited-copy-bound.rs b/src/test/compile-fail/kindck-inherited-copy-bound.rs index e146cac21a31c..0072b1228af48 100644 --- a/src/test/compile-fail/kindck-inherited-copy-bound.rs +++ b/src/test/compile-fail/kindck-inherited-copy-bound.rs @@ -15,6 +15,7 @@ use std::any::Any; trait Foo : Copy { + fn foo(&self) {} } impl Foo for T { diff --git a/src/test/compile-fail/regions-close-object-into-object-5.rs b/src/test/compile-fail/regions-close-object-into-object-5.rs index 05c6c6d9f9e02..bdc52eca2cb2d 100644 --- a/src/test/compile-fail/regions-close-object-into-object-5.rs +++ b/src/test/compile-fail/regions-close-object-into-object-5.rs @@ -11,8 +11,6 @@ #![feature(box_syntax)] #![allow(warnings)] -use std::marker::MarkerTrait; - trait A { fn get(&self) -> T { panic!() } @@ -20,7 +18,7 @@ trait A struct B<'a, T>(&'a (A+'a)); -trait X : MarkerTrait {} +trait X { fn foo(&self) {} } impl<'a, T> X for B<'a, T> {} diff --git a/src/test/compile-fail/regions-close-param-into-object.rs b/src/test/compile-fail/regions-close-param-into-object.rs index 9ad49a6703ee3..655ac6f66c97d 100644 --- a/src/test/compile-fail/regions-close-param-into-object.rs +++ b/src/test/compile-fail/regions-close-param-into-object.rs @@ -10,7 +10,7 @@ #![feature(box_syntax)] -trait X : ::std::marker::MarkerTrait {} +trait X { fn foo(&self) {} } fn p1(v: T) -> Box where T : X diff --git a/src/test/run-pass/borrowck-trait-lifetime.rs b/src/test/run-pass/borrowck-trait-lifetime.rs index be0c88f557cc7..a2b0fa5663530 100644 --- a/src/test/run-pass/borrowck-trait-lifetime.rs +++ b/src/test/run-pass/borrowck-trait-lifetime.rs @@ -16,7 +16,7 @@ use std::marker; fn main() { - trait T : marker::MarkerTrait {} + trait T { fn foo(&self) {} } fn f<'a, V: T>(v: &'a V) -> &'a T { v as &'a T diff --git a/src/test/run-pass/issue-14399.rs b/src/test/run-pass/issue-14399.rs index 4f3db1352bbd2..db7eacce9d10b 100644 --- a/src/test/run-pass/issue-14399.rs +++ b/src/test/run-pass/issue-14399.rs @@ -19,7 +19,7 @@ #[derive(Clone)] struct B1; -trait A : std::marker::MarkerTrait {} +trait A { fn foo(&self) {} } impl A for B1 {} fn main() { diff --git a/src/test/run-pass/trait-impl.rs b/src/test/run-pass/trait-impl.rs index bd2bf430a686c..7db1d7d031e3c 100644 --- a/src/test/run-pass/trait-impl.rs +++ b/src/test/run-pass/trait-impl.rs @@ -16,7 +16,8 @@ use traitimpl::Bar; static mut COUNT: uint = 1; -trait T : ::std::marker::MarkerTrait { +trait T { + fn foo(&self) {} } impl<'a> T+'a { diff --git a/src/test/run-pass/unique-object-move.rs b/src/test/run-pass/unique-object-move.rs index 1d4eb0a75232d..f01a56142e073 100644 --- a/src/test/run-pass/unique-object-move.rs +++ b/src/test/run-pass/unique-object-move.rs @@ -13,7 +13,7 @@ #![allow(unknown_features)] #![feature(box_syntax)] -pub trait EventLoop : ::std::marker::MarkerTrait { } +pub trait EventLoop { fn foo(&self) {} } pub struct UvEventLoop { uvio: int From 63f51ee90ccc1b7ab3a749ba7dbd4a3c76961c16 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 18 Feb 2015 19:35:20 -0500 Subject: [PATCH 72/76] Exempt phantom fns from the object safety check --- src/librustc/middle/traits/object_safety.rs | 9 +++--- .../compile-fail/object-safety-phantom-fn.rs | 28 +++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 src/test/compile-fail/object-safety-phantom-fn.rs diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs index a8f8d54cba9f5..f10f7eb3951c7 100644 --- a/src/librustc/middle/traits/object_safety.rs +++ b/src/librustc/middle/traits/object_safety.rs @@ -138,10 +138,11 @@ fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>, match predicate { ty::Predicate::Trait(ref data) => { // In the case of a trait predicate, we can skip the "self" type. - data.0.trait_ref.substs.types.get_slice(TypeSpace) - .iter() - .cloned() - .any(is_self) + Some(data.def_id()) != tcx.lang_items.phantom_fn() && + data.0.trait_ref.substs.types.get_slice(TypeSpace) + .iter() + .cloned() + .any(is_self) } ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) | diff --git a/src/test/compile-fail/object-safety-phantom-fn.rs b/src/test/compile-fail/object-safety-phantom-fn.rs new file mode 100644 index 0000000000000..fb30ce5c2455c --- /dev/null +++ b/src/test/compile-fail/object-safety-phantom-fn.rs @@ -0,0 +1,28 @@ +// Copyright 2014 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. + +// Check that `Self` appearing in a phantom fn does not make a trait not object safe. + +#![feature(rustc_attrs)] + +trait Baz : PhantomFn { +} + +fn make_bar>(t: &T) -> &Bar { + t +} + +fn make_baz(t: &T) -> &Baz { + t +} + +#[rustc_error] +fn main() { //~ ERROR compilation successful +} From b7c0813eb74db4706f7eb1943d0160e6501f6bc1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 18 Feb 2015 16:39:32 -0800 Subject: [PATCH 73/76] Round 4 test fixes and rebase conflicts --- src/libcollections/lib.rs | 2 +- src/libcollections/linked_list.rs | 2 +- src/libcollections/slice.rs | 4 +- src/libcore/marker.rs | 6 +- src/libstd/sys/windows/c.rs | 2 +- src/libstd/sys/windows/process.rs | 166 +++++++++++++++++- .../compile-fail/object-safety-phantom-fn.rs | 6 + ...c-type-in-supertrait-outlives-container.rs | 3 - ...egions-assoc-type-outlives-container-wc.rs | 3 - .../regions-assoc-type-outlives-container.rs | 3 - src/test/run-pass/trait-impl.rs | 2 +- 11 files changed, 180 insertions(+), 19 deletions(-) diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 8fce626755ee3..6569ab9c05acd 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -147,7 +147,6 @@ mod std { #[cfg(test)] mod prelude { // from core. - pub use core::borrow::IntoCow; pub use core::clone::Clone; pub use core::cmp::{PartialEq, Eq, PartialOrd, Ord}; pub use core::cmp::Ordering::{Less, Equal, Greater}; @@ -173,6 +172,7 @@ mod prelude { pub use unicode::char::CharExt; // from collections. + pub use borrow::IntoCow; pub use slice::SliceConcatExt; pub use string::{String, ToString}; pub use vec::Vec; diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 1c4b34b4650f7..c142819a51896 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -1041,7 +1041,7 @@ mod tests { } #[cfg(test)] - fn list_from(v: &[T]) -> DList { + fn list_from(v: &[T]) -> LinkedList { v.iter().cloned().collect() } diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 0abe7f120eaca..776b8b3af147c 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1997,9 +1997,9 @@ mod tests { #[test] fn test_lexicographic_permutations_empty_and_short() { - let empty : &mut[i32] = &mut[..]; + let empty : &mut[i32] = &mut[]; assert!(empty.next_permutation() == false); - let b: &mut[i32] = &mut[..]; + let b: &mut[i32] = &mut[]; assert!(empty == b); assert!(empty.prev_permutation() == false); assert!(empty == b); diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index dbe6db86adab5..d284eb341792b 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -301,7 +301,7 @@ impl MarkerTrait for T { } /// As an example, consider a trait with no methods like `Even`, meant /// to represent types that are "even": /// -/// ```rust +/// ```rust,ignore /// trait Even { } /// ``` /// @@ -310,7 +310,7 @@ impl MarkerTrait for T { } /// categorize types (and hence instances of those types) as "even" or /// not, so if we *were* going to have a method, it might look like: /// -/// ```rust +/// ```rust,ignore /// trait Even { /// fn is_even(self) -> bool { true } /// } @@ -319,7 +319,7 @@ impl MarkerTrait for T { } /// Therefore, we can model a method like this as follows: /// /// ```rust -/// use std::marker::PhantomFn +/// use std::marker::PhantomFn; /// trait Even : PhantomFn { } /// ``` /// diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index f861255a00a14..2d1a5e10bd63f 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -283,7 +283,7 @@ pub mod compat { fallback: usize) -> usize { let mut module: Vec = module.utf16_units().collect(); module.push(0); - let symbol = CString::from_slice(symbol.as_bytes()); + let symbol = CString::new(symbol).unwrap(); let func = unsafe { let handle = GetModuleHandleW(module.as_ptr()); GetProcAddress(handle, symbol.as_ptr()) as usize diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 96ffc4daddd4e..e001cd9a1ec8b 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -10,7 +10,7 @@ use prelude::v1::*; -use collections::hash_map::Hasher; +#[cfg(stage0)] use collections::hash_map::Hasher; use collections; use env; use ffi::CString; @@ -106,6 +106,7 @@ impl Process { } #[allow(deprecated)] + #[cfg(stage0)] pub fn spawn(cfg: &C, in_fd: Option

, out_fd: Option

, err_fd: Option

) -> IoResult @@ -267,6 +268,169 @@ impl Process { }) } } + #[allow(deprecated)] + #[cfg(not(stage0))] + pub fn spawn(cfg: &C, in_fd: Option

, + out_fd: Option

, err_fd: Option

) + -> IoResult + where C: ProcessConfig, P: AsInner, + K: BytesContainer + Eq + Hash, V: BytesContainer + { + use libc::types::os::arch::extra::{DWORD, HANDLE, STARTUPINFO}; + use libc::consts::os::extra::{ + TRUE, FALSE, + STARTF_USESTDHANDLES, + INVALID_HANDLE_VALUE, + DUPLICATE_SAME_ACCESS + }; + use libc::funcs::extra::kernel32::{ + GetCurrentProcess, + DuplicateHandle, + CloseHandle, + CreateProcessW + }; + use libc::funcs::extra::msvcrt::get_osfhandle; + + use mem; + use iter::IteratorExt; + use str::StrExt; + + if cfg.gid().is_some() || cfg.uid().is_some() { + return Err(IoError { + kind: old_io::IoUnavailable, + desc: "unsupported gid/uid requested on windows", + detail: None, + }) + } + + // To have the spawning semantics of unix/windows stay the same, we need to + // read the *child's* PATH if one is provided. See #15149 for more details. + let program = cfg.env().and_then(|env| { + for (key, v) in env { + if b"PATH" != key.container_as_bytes() { continue } + + // Split the value and test each path to see if the + // program exists. + for path in os::split_paths(v.container_as_bytes()) { + let path = path.join(cfg.program().as_bytes()) + .with_extension(env::consts::EXE_EXTENSION); + if path.exists() { + return Some(CString::from_slice(path.as_vec())) + } + } + break + } + None + }); + + unsafe { + let mut si = zeroed_startupinfo(); + si.cb = mem::size_of::() as DWORD; + si.dwFlags = STARTF_USESTDHANDLES; + + let cur_proc = GetCurrentProcess(); + + // Similarly to unix, we don't actually leave holes for the stdio file + // descriptors, but rather open up /dev/null equivalents. These + // equivalents are drawn from libuv's windows process spawning. + let set_fd = |fd: &Option

, slot: &mut HANDLE, + is_stdin: bool| { + match *fd { + None => { + let access = if is_stdin { + libc::FILE_GENERIC_READ + } else { + libc::FILE_GENERIC_WRITE | libc::FILE_READ_ATTRIBUTES + }; + let size = mem::size_of::(); + let mut sa = libc::SECURITY_ATTRIBUTES { + nLength: size as libc::DWORD, + lpSecurityDescriptor: ptr::null_mut(), + bInheritHandle: 1, + }; + let mut filename: Vec = "NUL".utf16_units().collect(); + filename.push(0); + *slot = libc::CreateFileW(filename.as_ptr(), + access, + libc::FILE_SHARE_READ | + libc::FILE_SHARE_WRITE, + &mut sa, + libc::OPEN_EXISTING, + 0, + ptr::null_mut()); + if *slot == INVALID_HANDLE_VALUE { + return Err(super::last_error()) + } + } + Some(ref fd) => { + let orig = get_osfhandle(fd.as_inner().fd()) as HANDLE; + if orig == INVALID_HANDLE_VALUE { + return Err(super::last_error()) + } + if DuplicateHandle(cur_proc, orig, cur_proc, slot, + 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE { + return Err(super::last_error()) + } + } + } + Ok(()) + }; + + try!(set_fd(&in_fd, &mut si.hStdInput, true)); + try!(set_fd(&out_fd, &mut si.hStdOutput, false)); + try!(set_fd(&err_fd, &mut si.hStdError, false)); + + let cmd_str = make_command_line(program.as_ref().unwrap_or(cfg.program()), + cfg.args()); + let mut pi = zeroed_process_information(); + let mut create_err = None; + + // stolen from the libuv code. + let mut flags = libc::CREATE_UNICODE_ENVIRONMENT; + if cfg.detach() { + flags |= libc::DETACHED_PROCESS | libc::CREATE_NEW_PROCESS_GROUP; + } + + with_envp(cfg.env(), |envp| { + with_dirp(cfg.cwd(), |dirp| { + let mut cmd_str: Vec = cmd_str.utf16_units().collect(); + cmd_str.push(0); + let _lock = CREATE_PROCESS_LOCK.lock().unwrap(); + let created = CreateProcessW(ptr::null(), + cmd_str.as_mut_ptr(), + ptr::null_mut(), + ptr::null_mut(), + TRUE, + flags, envp, dirp, + &mut si, &mut pi); + if created == FALSE { + create_err = Some(super::last_error()); + } + }) + }); + + assert!(CloseHandle(si.hStdInput) != 0); + assert!(CloseHandle(si.hStdOutput) != 0); + assert!(CloseHandle(si.hStdError) != 0); + + match create_err { + Some(err) => return Err(err), + None => {} + } + + // We close the thread handle because we don't care about keeping the + // thread id valid, and we aren't keeping the thread handle around to be + // able to close it later. We don't close the process handle however + // because std::we want the process id to stay valid at least until the + // calling code closes the process handle. + assert!(CloseHandle(pi.hThread) != 0); + + Ok(Process { + pid: pi.dwProcessId as pid_t, + handle: pi.hProcess as *mut () + }) + } + } /// Waits for a process to exit and returns the exit code, failing /// if there is no process with the specified id. diff --git a/src/test/compile-fail/object-safety-phantom-fn.rs b/src/test/compile-fail/object-safety-phantom-fn.rs index fb30ce5c2455c..1c95ee43d27af 100644 --- a/src/test/compile-fail/object-safety-phantom-fn.rs +++ b/src/test/compile-fail/object-safety-phantom-fn.rs @@ -11,10 +11,16 @@ // Check that `Self` appearing in a phantom fn does not make a trait not object safe. #![feature(rustc_attrs)] +#![allow(dead_code)] + +use std::marker::PhantomFn; trait Baz : PhantomFn { } +trait Bar : PhantomFn<(Self, T)> { +} + fn make_bar>(t: &T) -> &Bar { t } diff --git a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs index fa26c9c54c8f4..e96c345034bce 100644 --- a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs +++ b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs @@ -15,9 +15,6 @@ #![allow(dead_code)] -use std::mem::transmute; -use std::ops::Deref; - /////////////////////////////////////////////////////////////////////////// pub trait TheTrait { diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs index 6ee65fbdf919b..6d8a02ab17480 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs @@ -15,9 +15,6 @@ #![allow(dead_code)] -use std::mem::transmute; -use std::ops::Deref; - /////////////////////////////////////////////////////////////////////////// pub trait TheTrait { diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-outlives-container.rs index 49a0726fa3b7b..5fafec50a4b58 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container.rs @@ -14,9 +14,6 @@ #![allow(dead_code)] -use std::mem::transmute; -use std::ops::Deref; - /////////////////////////////////////////////////////////////////////////// pub trait TheTrait { diff --git a/src/test/run-pass/trait-impl.rs b/src/test/run-pass/trait-impl.rs index 7db1d7d031e3c..325fba8a0ee42 100644 --- a/src/test/run-pass/trait-impl.rs +++ b/src/test/run-pass/trait-impl.rs @@ -17,7 +17,7 @@ use traitimpl::Bar; static mut COUNT: uint = 1; trait T { - fn foo(&self) {} + fn t(&self) {} } impl<'a> T+'a { From cb29c468f38ba93f624277c2c3a8e46a4d85e619 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 18 Feb 2015 18:01:03 -0800 Subject: [PATCH 74/76] Fix from niko for cfail tests --- src/librustc_typeck/check/implicator.rs | 8 ++++++++ ...regions-assoc-type-in-supertrait-outlives-container.rs | 6 +++--- .../regions-assoc-type-outlives-container-hrtb.rs | 6 +++--- .../regions-assoc-type-outlives-container-wc.rs | 6 +++--- .../compile-fail/regions-assoc-type-outlives-container.rs | 7 ++++--- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/librustc_typeck/check/implicator.rs b/src/librustc_typeck/check/implicator.rs index da25719baaa4a..4aaaf4ffe5ab3 100644 --- a/src/librustc_typeck/check/implicator.rs +++ b/src/librustc_typeck/check/implicator.rs @@ -329,6 +329,9 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { fn accumulate_from_assoc_types_transitive(&mut self, data: &ty::PolyTraitPredicate<'tcx>) { + debug!("accumulate_from_assoc_types_transitive({})", + data.repr(self.tcx())); + for poly_trait_ref in traits::supertraits(self.tcx(), data.to_poly_trait_ref()) { match ty::no_late_bound_regions(self.tcx(), &poly_trait_ref) { Some(trait_ref) => { self.accumulate_from_assoc_types(trait_ref); } @@ -340,6 +343,9 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { fn accumulate_from_assoc_types(&mut self, trait_ref: Rc>) { + debug!("accumulate_from_assoc_types({})", + trait_ref.repr(self.tcx())); + let trait_def_id = trait_ref.def_id; let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id); let assoc_type_projections: Vec<_> = @@ -347,6 +353,8 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { .iter() .map(|&name| ty::mk_projection(self.tcx(), trait_ref.clone(), name)) .collect(); + debug!("accumulate_from_assoc_types: assoc_type_projections={}", + assoc_type_projections.repr(self.tcx())); let tys = match self.fully_normalize(&assoc_type_projections) { Ok(tys) => { tys } Err(ErrorReported) => { return; } diff --git a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs index e96c345034bce..6aa0cc003ce64 100644 --- a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs +++ b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs @@ -15,12 +15,12 @@ #![allow(dead_code)] +use std::marker::PhantomFn; + /////////////////////////////////////////////////////////////////////////// -pub trait TheTrait { +pub trait TheTrait: PhantomFn { type TheAssocType; - - fn dummy(&self) { } } pub trait TheSubTrait : TheTrait { diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs index 7d955065ff455..dd89e0e038b24 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs @@ -14,12 +14,12 @@ #![allow(dead_code)] #![feature(rustc_attrs)] +use std::marker::PhantomFn; + /////////////////////////////////////////////////////////////////////////// -pub trait TheTrait<'b> { +pub trait TheTrait<'b> : PhantomFn { type TheAssocType; - - fn dummy(&'b self) { } } pub struct TheType<'b> { diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs index 6d8a02ab17480..da7546ce21c60 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs @@ -15,12 +15,12 @@ #![allow(dead_code)] +use std::marker::PhantomFn; + /////////////////////////////////////////////////////////////////////////// -pub trait TheTrait { +pub trait TheTrait: PhantomFn { type TheAssocType; - - fn dummy(&self) { } } pub struct TheType<'b> { diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-outlives-container.rs index 5fafec50a4b58..e1e72e6f56e93 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container.rs @@ -13,13 +13,14 @@ // outlive the location in which the type appears. Issue #22246. #![allow(dead_code)] +#![feature(rustc_attrs)] + +use std::marker::PhantomFn; /////////////////////////////////////////////////////////////////////////// -pub trait TheTrait { +pub trait TheTrait: PhantomFn { type TheAssocType; - - fn dummy(&self) { } } pub struct TheType<'b> { From 0cd54b85ef1fdad3bc4c1c4e1a989b9f6540a0fa Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 18 Feb 2015 18:02:58 -0800 Subject: [PATCH 75/76] Round 5 test fixes and rebase conflicts --- src/libcore/hash/mod.rs | 4 +-- src/libstd/old_io/process.rs | 14 ++++++++- src/libstd/os.rs | 5 ++-- src/libstd/sys/unix/os.rs | 2 +- src/libstd/sys/windows/backtrace.rs | 4 +-- src/libstd/sys/windows/process.rs | 29 +++++++++++++++++++ ...ions-assoc-type-outlives-container-hrtb.rs | 2 +- src/test/run-make/save-analysis/foo.rs | 2 +- 8 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index 1086ae84ded6d..2e83334b93732 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -158,7 +158,7 @@ pub trait Hasher { #[inline] #[unstable(feature = "hash", reason = "module was recently redesigned")] fn write_usize(&mut self, i: usize) { - if cfg!(target_pointer_size = "32") { + if cfg!(target_pointer_width = "32") { self.write_u32(i as u32) } else { self.write_u64(i as u64) @@ -241,7 +241,7 @@ mod impls { #[inline] fn hash(&self, state: &mut S) { let a: [u8; ::$ty::BYTES] = unsafe { - mem::transmute((*self as $uty).to_le() as $ty) + mem::transmute(*self) }; state.write(&a) } diff --git a/src/libstd/old_io/process.rs b/src/libstd/old_io/process.rs index c761bf705a81f..c803cfbcb7d85 100644 --- a/src/libstd/old_io/process.rs +++ b/src/libstd/old_io/process.rs @@ -104,7 +104,7 @@ struct EnvKey(CString); #[derive(Eq, Clone, Debug)] struct EnvKey(CString); -#[cfg(windows)] +#[cfg(all(windows, stage0))] impl hash::Hash for EnvKey { fn hash(&self, state: &mut H) { let &EnvKey(ref x) = self; @@ -116,6 +116,18 @@ impl hash::Hash for EnvKey { } } } +#[cfg(all(windows, not(stage0)))] +impl hash::Hash for EnvKey { + fn hash(&self, state: &mut H) { + let &EnvKey(ref x) = self; + match str::from_utf8(x.as_bytes()) { + Ok(s) => for ch in s.chars() { + (ch as u8 as char).to_lowercase().hash(state); + }, + Err(..) => x.hash(state) + } + } +} #[cfg(windows)] impl PartialEq for EnvKey { diff --git a/src/libstd/os.rs b/src/libstd/os.rs index a4213e7373b1e..f181fc5df5759 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -561,10 +561,11 @@ pub fn get_exit_status() -> int { #[cfg(target_os = "macos")] unsafe fn load_argc_and_argv(argc: int, argv: *const *const c_char) -> Vec> { + use ffi::CStr; use iter::range; - (0..argc as uint).map(|i| { - ffi::c_str_to_bytes(&*argv.offset(i as int)).to_vec() + (0..argc).map(|i| { + CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec() }).collect() } diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 66856a2f2c221..3d1ef3a2c37f7 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -266,7 +266,7 @@ pub fn args() -> Args { let (argc, argv) = (*_NSGetArgc() as isize, *_NSGetArgv() as *const *const c_char); range(0, argc as isize).map(|i| { - let bytes = CStr::from_ptr(&*argv.offset(i)).to_bytes().to_vec(); + let bytes = CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec(); OsStringExt::from_vec(bytes) }).collect::>() }; diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs index 92e309da34bef..51cf30324233c 100644 --- a/src/libstd/sys/windows/backtrace.rs +++ b/src/libstd/sys/windows/backtrace.rs @@ -25,7 +25,7 @@ #![allow(dead_code)] use dynamic_lib::DynamicLibrary; -use ffi; +use ffi::CStr; use intrinsics; use old_io::{IoResult, Writer}; use libc; @@ -362,7 +362,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> { if ret == libc::TRUE { try!(write!(w, " - ")); let ptr = info.Name.as_ptr() as *const libc::c_char; - let bytes = unsafe { ffi::c_str_to_bytes(&ptr) }; + let bytes = unsafe { CStr::from_ptr(ptr).to_bytes() }; match str::from_utf8(bytes) { Ok(s) => try!(demangle(w, s)), Err(..) => try!(w.write_all(&bytes[..bytes.len()-1])), diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index e001cd9a1ec8b..60d24e6174fd7 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -589,6 +589,7 @@ fn make_command_line(prog: &CString, args: &[CString]) -> String { } } +#[cfg(stage0)] fn with_envp(env: Option<&collections::HashMap>, cb: F) -> T where K: BytesContainer + Eq + Hash, V: BytesContainer, @@ -616,6 +617,34 @@ fn with_envp(env: Option<&collections::HashMap>, cb: F) -> T _ => cb(ptr::null_mut()) } } +#[cfg(not(stage0))] +fn with_envp(env: Option<&collections::HashMap>, cb: F) -> T + where K: BytesContainer + Eq + Hash, + V: BytesContainer, + F: FnOnce(*mut c_void) -> T, +{ + // On Windows we pass an "environment block" which is not a char**, but + // rather a concatenation of null-terminated k=v\0 sequences, with a final + // \0 to terminate. + match env { + Some(env) => { + let mut blk = Vec::new(); + + for pair in env { + let kv = format!("{}={}", + pair.0.container_as_str().unwrap(), + pair.1.container_as_str().unwrap()); + blk.extend(kv.utf16_units()); + blk.push(0); + } + + blk.push(0); + + cb(blk.as_mut_ptr() as *mut c_void) + } + _ => cb(ptr::null_mut()) + } +} fn with_dirp(d: Option<&CString>, cb: F) -> T where F: FnOnce(*const u16) -> T, diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs index dd89e0e038b24..9736910d7b5fe 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs @@ -18,7 +18,7 @@ use std::marker::PhantomFn; /////////////////////////////////////////////////////////////////////////// -pub trait TheTrait<'b> : PhantomFn { +pub trait TheTrait<'b> : PhantomFn<&'b Self,Self> { type TheAssocType; } diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make/save-analysis/foo.rs index b6366ad67375a..38381da3670c1 100644 --- a/src/test/run-make/save-analysis/foo.rs +++ b/src/test/run-make/save-analysis/foo.rs @@ -34,7 +34,7 @@ use std::mem::size_of; static uni: &'static str = "Les Miséééééééérables"; static yy: usize = 25; -static bob: Option> = None; +static bob: Option<&'static [isize]> = None; // buglink test - see issue #1337. From 49771bafa5fca16486bfd06741dac3de2c587adf Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 19 Feb 2015 23:18:20 +0530 Subject: [PATCH 76/76] Round 8 tex fixes --- src/libstd/sys/windows/process2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/windows/process2.rs b/src/libstd/sys/windows/process2.rs index 4e36ed2f17f92..19e38196d199f 100644 --- a/src/libstd/sys/windows/process2.rs +++ b/src/libstd/sys/windows/process2.rs @@ -472,7 +472,7 @@ mod tests { "echo \"a b c\"" ); assert_eq!( - test_wrapper("\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}", &[..]), + test_wrapper("\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}", &[]), "\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}" ); }

Parser for P { type Input = (); } diff --git a/src/test/run-pass/associated-types-nested-projections.rs b/src/test/run-pass/associated-types-nested-projections.rs index e3227613159d1..2ee8ef0d3ddac 100644 --- a/src/test/run-pass/associated-types-nested-projections.rs +++ b/src/test/run-pass/associated-types-nested-projections.rs @@ -10,11 +10,12 @@ // Test that we can resolve nested projection types. Issue #20666. +use std::marker::MarkerTrait; use std::slice; -trait Bound {} +trait Bound : MarkerTrait {} -impl<'a> Bound for &'a int {} +impl<'a> Bound for &'a i32 {} trait IntoIterator { type Iter: Iterator; diff --git a/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs b/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs index dd5814f875b08..de96af83f5917 100644 --- a/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs +++ b/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs @@ -13,7 +13,9 @@ #![allow(dead_code)] -pub trait Integral { +use std::marker::MarkerTrait; + +pub trait Integral : MarkerTrait { type Opposite; } @@ -27,6 +29,8 @@ impl Integral for u32 { pub trait FnLike { type R; + + fn dummy(&self, a: A) -> Self::R { loop { } } } fn foo() diff --git a/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs b/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs index 1d264655bc479..8617750ca538e 100644 --- a/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs +++ b/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs @@ -11,15 +11,17 @@ // Test that we normalize associated types that appear in bounds; if // we didn't, the call to `self.split2()` fails to type check. -struct Splits<'a, T, P>; -struct SplitsN; +use std::marker::PhantomData; + +struct Splits<'a, T:'a, P>(PhantomData<(&'a T, P)>); +struct SplitsN(PhantomData); trait SliceExt2 { type Item; fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P> where P: FnMut(&Self::Item) -> bool; - fn splitn2<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> + fn splitn2<'a, P>(&'a self, n: u32, pred: P) -> SplitsN> where P: FnMut(&Self::Item) -> bool; } @@ -30,7 +32,7 @@ impl SliceExt2 for [T] { loop {} } - fn splitn2