]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #60763 - matklad:tt-parser, r=petrochenkov
authorbors <bors@rust-lang.org>
Thu, 16 May 2019 04:15:12 +0000 (04:15 +0000)
committerbors <bors@rust-lang.org>
Thu, 16 May 2019 04:15:12 +0000 (04:15 +0000)
Move token tree related lexer state to a separate struct

Just a types-based refactoring.

We only used a bunch of fields when tokenizing into a token tree, so let's move them out of the base lexer

273 files changed:
RELEASES.md
src/bootstrap/bootstrap.py
src/bootstrap/native.rs
src/bootstrap/test.rs
src/build_helper/lib.rs
src/liballoc/collections/binary_heap.rs
src/liballoc/collections/btree/map.rs
src/liballoc/collections/btree/set.rs
src/liballoc/string.rs
src/liballoc/vec.rs
src/libcore/ascii.rs
src/libcore/future/future.rs
src/libcore/iter/adapters/mod.rs
src/libcore/ptr.rs
src/libcore/slice/mod.rs
src/libcore/str/mod.rs
src/libcore/tests/lib.rs
src/librustc/hir/check_attr.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/mod.rs
src/librustc/hir/mod.rs
src/librustc/hir/print.rs
src/librustc/ich/hcx.rs
src/librustc/ich/impls_syntax.rs
src/librustc/ich/mod.rs
src/librustc/infer/opaque_types/mod.rs
src/librustc/lint/levels.rs
src/librustc/lint/mod.rs
src/librustc/middle/dead.rs
src/librustc/middle/entry.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/lib_features.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/recursion_limit.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/middle/weak_lang_items.rs
src/librustc/query/mod.rs
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc/traits/coherence.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/on_unimplemented.rs
src/librustc/traits/project.rs
src/librustc/traits/select.rs
src/librustc/ty/context.rs
src/librustc/ty/layout.rs
src/librustc/ty/mod.rs
src/librustc/ty/util.rs
src/librustc_allocator/expand.rs
src/librustc_codegen_llvm/abi.rs
src/librustc_codegen_llvm/attributes.rs
src/librustc_codegen_llvm/builder.rs
src/librustc_codegen_llvm/consts.rs
src/librustc_codegen_llvm/debuginfo/gdb.rs
src/librustc_codegen_llvm/declare.rs
src/librustc_codegen_llvm/llvm_util.rs
src/librustc_codegen_llvm/type_.rs
src/librustc_codegen_llvm/type_of.rs
src/librustc_codegen_ssa/back/write.rs
src/librustc_codegen_ssa/mir/block.rs
src/librustc_codegen_ssa/mir/mod.rs
src/librustc_codegen_ssa/mir/rvalue.rs
src/librustc_codegen_ssa/traits/abi.rs
src/librustc_codegen_ssa/traits/builder.rs
src/librustc_codegen_ssa/traits/mod.rs
src/librustc_codegen_utils/lib.rs
src/librustc_codegen_utils/link.rs
src/librustc_codegen_utils/symbol_names_test.rs
src/librustc_data_structures/flock.rs
src/librustc_driver/lib.rs
src/librustc_driver/pretty.rs
src/librustc_incremental/assert_module_sources.rs
src/librustc_incremental/persist/dirty_clean.rs
src/librustc_interface/passes.rs
src/librustc_interface/proc_macro_decls.rs
src/librustc_interface/util.rs
src/librustc_lint/builtin.rs
src/librustc_lint/nonstandard_style.rs
src/librustc_lint/types.rs
src/librustc_lint/unused.rs
src/librustc_macros/src/symbols.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/link_args.rs
src/librustc_metadata/locator.rs
src/librustc_metadata/native_libs.rs
src/librustc_mir/borrow_check/error_reporting.rs
src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
src/librustc_mir/borrow_check/nll/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
src/librustc_mir/dataflow/mod.rs
src/librustc_mir/hair/cx/mod.rs
src/librustc_mir/hair/pattern/mod.rs
src/librustc_mir/interpret/cast.rs
src/librustc_mir/transform/check_unsafety.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/rustc_peek.rs
src/librustc_mir/util/borrowck_errors.rs
src/librustc_passes/ast_validation.rs
src/librustc_passes/layout_test.rs
src/librustc_passes/rvalue_promotion.rs
src/librustc_plugin/build.rs
src/librustc_plugin/load.rs
src/librustc_plugin/registry.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/lib.rs
src/librustc_target/spec/apple_base.rs
src/librustc_target/spec/bitrig_base.rs [deleted file]
src/librustc_target/spec/mod.rs
src/librustc_target/spec/x86_64_unknown_bitrig.rs [deleted file]
src/librustc_traits/lowering/mod.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/demand.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/outlives/mod.rs
src/librustc_typeck/outlives/test.rs
src/librustc_typeck/variance/test.rs
src/librustdoc/clean/cfg.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/core.rs
src/librustdoc/html/highlight.rs
src/librustdoc/html/render.rs
src/librustdoc/passes/calculate_doc_coverage.rs
src/librustdoc/passes/collect_intra_doc_links.rs
src/librustdoc/passes/collect_trait_impls.rs
src/librustdoc/passes/strip_hidden.rs
src/librustdoc/test.rs
src/librustdoc/visit_ast.rs
src/librustdoc/visit_lib.rs
src/libstd/build.rs
src/libstd/env.rs
src/libstd/error.rs
src/libstd/ffi/c_str.rs
src/libstd/net/addr.rs
src/libstd/net/tcp.rs
src/libstd/net/udp.rs
src/libstd/os/bitrig/fs.rs [deleted file]
src/libstd/os/bitrig/mod.rs [deleted file]
src/libstd/os/bitrig/raw.rs [deleted file]
src/libstd/os/mod.rs
src/libstd/path.rs
src/libstd/sys/unix/args.rs
src/libstd/sys/unix/env.rs
src/libstd/sys/unix/ext/net.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/mod.rs
src/libstd/sys/unix/os.rs
src/libstd/sys/unix/rand.rs
src/libstd/sys/unix/stack_overflow.rs
src/libstd/sys/unix/thread.rs
src/libstd/sys/wasm/args.rs
src/libstd/sys/windows/args.rs
src/libstd/sys_common/net.rs
src/libsyntax/ast.rs
src/libsyntax/attr/builtin.rs
src/libsyntax/attr/mod.rs
src/libsyntax/config.rs
src/libsyntax/entry.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/derive.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/source_util.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/feature_gate.rs
src/libsyntax/mut_visit.rs
src/libsyntax/parse/classify.rs
src/libsyntax/parse/lexer/comments.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/literal.rs [new file with mode: 0644]
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pprust.rs
src/libsyntax/std_inject.rs
src/libsyntax/test.rs
src/libsyntax_ext/asm.rs
src/libsyntax_ext/concat_idents.rs
src/libsyntax_ext/deriving/clone.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_ext/deriving/mod.rs
src/libsyntax_ext/format.rs
src/libsyntax_ext/global_asm.rs
src/libsyntax_ext/log_syntax.rs
src/libsyntax_ext/proc_macro_decls.rs
src/libsyntax_ext/test.rs
src/libsyntax_ext/test_case.rs
src/libsyntax_ext/trace_macros.rs
src/libsyntax_pos/edition.rs
src/libsyntax_pos/lib.rs
src/libsyntax_pos/symbol.rs
src/libtest/lib.rs
src/libunwind/build.rs
src/llvm-project
src/test/codegen/dllimports/main.rs
src/test/codegen/i686-no-macosx-deployment-target.rs
src/test/codegen/panic-abort-windows.rs
src/test/codegen/x86_64-no-macosx-deployment-target.rs
src/test/run-make-fulldeps/issue-14500/Makefile
src/test/run-make-fulldeps/tools.mk
src/test/run-make-fulldeps/use-extern-for-plugins/Makefile
src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs
src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs
src/test/run-pass-fulldeps/auxiliary/lint-for-crate.rs
src/test/run-pass/backtrace-debuginfo.rs
src/test/run-pass/consts/const-ptr-nonnull.rs
src/test/run-pass/dupe-first-attr.rc
src/test/run-pass/functions-closures/parallel-codegen-closures.rs
src/test/run-pass/impl-trait-in-bindings.rs
src/test/run-pass/impl-trait-in-bindings.stderr [new file with mode: 0644]
src/test/run-pass/impl-trait/lifetimes.rs
src/test/run-pass/intrinsics/intrinsic-alignment.rs
src/test/run-pass/sepcomp/sepcomp-cci.rs
src/test/run-pass/sepcomp/sepcomp-extern.rs
src/test/run-pass/sepcomp/sepcomp-fns-backwards.rs
src/test/run-pass/sepcomp/sepcomp-fns.rs
src/test/run-pass/sepcomp/sepcomp-statics.rs
src/test/run-pass/sepcomp/sepcomp-unwind.rs
src/test/run-pass/structs-enums/rec-align-u64.rs
src/test/run-pass/tcp-stress.rs
src/test/run-pass/x86stdcall.rs
src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs
src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs
src/test/ui-fulldeps/auxiliary/lint-tool-test.rs
src/test/ui/attr-eq-token-tree.stderr
src/test/ui/const-generics/cannot-infer-type-for-const-param.rs [new file with mode: 0644]
src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr [new file with mode: 0644]
src/test/ui/const-generics/invalid-const-arg-for-type-param.rs [new file with mode: 0644]
src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr [new file with mode: 0644]
src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr
src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr
src/test/ui/existential_types/issue-60655-latebound-regions.rs [new file with mode: 0644]
src/test/ui/impl-trait/bindings-opaque.rs
src/test/ui/impl-trait/bindings-opaque.stderr
src/test/ui/impl-trait/bindings.rs
src/test/ui/impl-trait/bindings.stderr
src/test/ui/impl-trait/can-return-unconstrained-closure.rs
src/test/ui/impl-trait/issue-57464-unexpected-regions.rs
src/test/ui/issues/issue-60662.rs [new file with mode: 0644]
src/test/ui/issues/issue-60662.stdout [new file with mode: 0644]
src/test/ui/macros/macro-attribute.stderr
src/test/ui/malformed/malformed-interpolated.rs
src/test/ui/malformed/malformed-interpolated.stderr
src/test/ui/nll/issue-55850.rs
src/test/ui/nll/issue-55850.stderr
src/test/ui/parser/attr-bad-meta-2.stderr
src/test/ui/parser/pat-tuple-5.stderr
src/test/ui/proc-macro/no-missing-docs.rs [new file with mode: 0644]
src/test/ui/save-analysis/issue-59134-0.rs [new file with mode: 0644]
src/test/ui/save-analysis/issue-59134-0.stderr [new file with mode: 0644]
src/test/ui/save-analysis/issue-59134-1.rs [new file with mode: 0644]
src/test/ui/save-analysis/issue-59134-1.stderr [new file with mode: 0644]
src/test/ui/traits/cycle-cache-err-60010.rs [new file with mode: 0644]
src/test/ui/traits/cycle-cache-err-60010.stderr [new file with mode: 0644]
src/tools/clippy
src/tools/compiletest/src/runtest.rs
src/tools/compiletest/src/util.rs
src/tools/miri

index 3b4f4182702d1146b6e75e5724e9d40a0ce1680e..48bd13105bbea92a5b431359095b3863c908cbb5 100644 (file)
@@ -1,3 +1,11 @@
+Version 1.34.2 (2019-05-14)
+===========================
+
+* [Destabilize the `Error::type_id` function due to a security
+   vulnerability][60785]
+
+[60785]: https://github.com/rust-lang/rust/pull/60785
+
 Version 1.34.1 (2019-04-25)
 ===========================
 
index 86c82adffa9b09bbccc99f899b19e37127847d8b..1c2b882f66594a45254e24f2e75a12183c29d43a 100644 (file)
@@ -177,7 +177,6 @@ def default_build_triple():
     # The goal here is to come up with the same triple as LLVM would,
     # at least for the subset of platforms we're willing to target.
     ostype_mapper = {
-        'Bitrig': 'unknown-bitrig',
         'Darwin': 'apple-darwin',
         'DragonFly': 'unknown-dragonfly',
         'FreeBSD': 'unknown-freebsd',
index 5777331b9bfd5b9ae67b0544ee4cba6136168fe0..da2e03a1a08482e6e6f912ee249a69056c884e51 100644 (file)
@@ -317,6 +317,10 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) {
 fn configure_cmake(builder: &Builder<'_>,
                    target: Interned<String>,
                    cfg: &mut cmake::Config) {
+    // Do not print installation messages for up-to-date files.
+    // LLVM and LLD builds can produce a lot of those and hit CI limits on log size.
+    cfg.define("CMAKE_INSTALL_MESSAGE", "LAZY");
+
     if builder.config.ninja {
         cfg.generator("Ninja");
     }
index 9867113e48f430c98fe89595afd7cd3cf01d2cb8..7826ac9471806043c1b00505e13cbe9ffab424c6 100644 (file)
@@ -1184,8 +1184,19 @@ fn run(self, builder: &Builder<'_>) {
                     Err(_) => p,
                 }
             })
-            .filter(|p| p.starts_with(suite_path) && p.is_file())
-            .map(|p| p.strip_prefix(suite_path).unwrap().to_str().unwrap())
+            .filter(|p| p.starts_with(suite_path) && (p.is_dir() || p.is_file()))
+            .filter_map(|p| {
+                // Since test suite paths are themselves directories, if we don't
+                // specify a directory or file, we'll get an empty string here
+                // (the result of the test suite directory without its suite prefix).
+                // Therefore, we need to filter these out, as only the first --test-args
+                // flag is respected, so providing an empty --test-args conflicts with
+                // any following it.
+                match p.strip_prefix(suite_path).ok().and_then(|p| p.to_str()) {
+                    Some(s) if s != "" => Some(s),
+                    _ => None,
+                }
+            })
             .collect();
 
         test_args.append(&mut builder.config.cmd.test_args());
index bd99dc118e66a36ab2f819aac565669f2fc947c3..60911d917899f6f338da76cd30a96dfbadd470a4 100644 (file)
@@ -113,7 +113,7 @@ pub fn gnu_target(target: &str) -> &str {
 }
 
 pub fn make(host: &str) -> PathBuf {
-    if host.contains("bitrig") || host.contains("dragonfly") || host.contains("freebsd")
+    if host.contains("dragonfly") || host.contains("freebsd")
         || host.contains("netbsd") || host.contains("openbsd")
     {
         PathBuf::from("gmake")
index c355361b53c4690b3f346775d07d632f1fbb3bf4..39fcfaa789377bb575fabda5be8fccc790468885 100644 (file)
@@ -992,6 +992,11 @@ fn next(&mut self) -> Option<&'a T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1047,6 +1052,11 @@ fn next(&mut self) -> Option<T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1093,6 +1103,11 @@ fn next(&mut self) -> Option<T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "drain", since = "1.6.0")]
index 6b079fc87cc78905f431a097a2aa8aaee7a33f3b..414abb00ef1fa760161d49cbaa0327939675ce94 100644 (file)
@@ -1193,6 +1193,11 @@ fn next(&mut self) -> Option<(&'a K, &'a V)> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         (self.length, Some(self.length))
     }
+
+    #[inline]
+    fn last(mut self) -> Option<(&'a K, &'a V)> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
@@ -1253,6 +1258,11 @@ fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         (self.length, Some(self.length))
     }
+
+    #[inline]
+    fn last(mut self) -> Option<(&'a K, &'a mut V)> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1359,6 +1369,11 @@ fn next(&mut self) -> Option<(K, V)> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         (self.length, Some(self.length))
     }
+
+    #[inline]
+    fn last(mut self) -> Option<(K, V)> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1421,6 +1436,11 @@ fn next(&mut self) -> Option<&'a K> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a K> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1458,6 +1478,11 @@ fn next(&mut self) -> Option<&'a V> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a V> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1495,6 +1520,11 @@ fn next(&mut self) -> Option<(&'a K, &'a V)> {
             unsafe { Some(self.next_unchecked()) }
         }
     }
+
+    #[inline]
+    fn last(mut self) -> Option<(&'a K, &'a V)> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "map_values_mut", since = "1.10.0")]
@@ -1508,6 +1538,11 @@ fn next(&mut self) -> Option<&'a mut V> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a mut V> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "map_values_mut", since = "1.10.0")]
@@ -1626,6 +1661,11 @@ fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
             unsafe { Some(self.next_unchecked()) }
         }
     }
+
+    #[inline]
+    fn last(mut self) -> Option<(&'a K, &'a mut V)> {
+        self.next_back()
+    }
 }
 
 impl<'a, K, V> RangeMut<'a, K, V> {
index 16a96ca19b82462b4a99f2e234f3e1c85b630e4f..6f2467dfd6b513de6b41e7fec1a95a85f61feed9 100644 (file)
@@ -1019,6 +1019,11 @@ fn next(&mut self) -> Option<&'a T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a T> {
+        self.next_back()
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
@@ -1044,6 +1049,11 @@ fn next(&mut self) -> Option<T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<T> {
+        self.next_back()
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> DoubleEndedIterator for IntoIter<T> {
@@ -1073,6 +1083,11 @@ impl<'a, T> Iterator for Range<'a, T> {
     fn next(&mut self) -> Option<&'a T> {
         self.iter.next().map(|(k, _)| k)
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "btree_range", since = "1.17.0")]
index 3fdcf95ccaa3f7a375e53c92a5b73a2823a6af46..63f7769fee56a794583404c020b421c6354373e7 100644 (file)
@@ -2377,6 +2377,10 @@ fn next(&mut self) -> Option<char> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+    #[inline]
+    fn last(mut self) -> Option<char> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "drain", since = "1.6.0")]
index 073d3ab5937035a148053e8e6243a8c300903ab2..c0cdffe596babc85e61fce4813ef1616682df183 100644 (file)
@@ -2395,6 +2395,11 @@ fn size_hint(&self) -> (usize, Option<usize>) {
     fn count(self) -> usize {
         self.len()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2514,6 +2519,11 @@ fn next(&mut self) -> Option<T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "drain", since = "1.6.0")]
@@ -2583,6 +2593,10 @@ fn next(&mut self) -> Option<Self::Item> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.drain.size_hint()
     }
+
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "vec_splice", since = "1.21.0")]
index c0ab364380fbd83d379fe22662e5d4eb20f80598..ddee02ea232d1cf43f6428b8f82440ba21b4c943 100644 (file)
@@ -117,6 +117,8 @@ impl Iterator for EscapeDefault {
     type Item = u8;
     fn next(&mut self) -> Option<u8> { self.range.next().map(|i| self.data[i]) }
     fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
+    #[inline]
+    fn last(mut self) -> Option<u8> { self.next_back() }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl DoubleEndedIterator for EscapeDefault {
index 504330a023b31408115f2c8fbdb8c902d25fcf36..3f76ac20192ba092734225342772b827165e627b 100644 (file)
@@ -23,7 +23,7 @@
 /// When using a future, you generally won't call `poll` directly, but instead
 /// `await!` the value.
 #[doc(spotlight)]
-#[must_use = "futures do nothing unless polled"]
+#[must_use = "futures do nothing unless you `.await` or poll them"]
 #[stable(feature = "futures_api", since = "1.36.0")]
 pub trait Future {
     /// The type of value produced on completion.
index 518442efe74172a3c35ed85a23c00ff979681d72..64e588f65b4688b5800b4c616455fc2a17b66c35 100644 (file)
@@ -73,6 +73,11 @@ fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
     {
         self.iter.position(predicate)
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
index a4e7ea5eff5ba35a182b81bca30762b9a5d984db..b6de9f57b0110439227d2ba8ae5797761595b922 100644 (file)
@@ -2970,7 +2970,6 @@ impl<T: Sized> NonNull<T> {
     /// some other means.
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[inline]
-    #[rustc_const_unstable(feature = "const_ptr_nonnull")]
     pub const fn dangling() -> Self {
         unsafe {
             let ptr = mem::align_of::<T>() as *mut T;
@@ -3034,7 +3033,6 @@ pub unsafe fn as_mut(&mut self) -> &mut T {
     /// Cast to a pointer of another type
     #[stable(feature = "nonnull_cast", since = "1.27.0")]
     #[inline]
-    #[rustc_const_unstable(feature = "const_ptr_nonnull")]
     pub const fn cast<U>(self) -> NonNull<U> {
         unsafe {
             NonNull::new_unchecked(self.as_ptr() as *mut U)
index 8731f48675356e399b63d490f7f4fcc268b13041..d06d107d32a41cabbe8a3fca7e35bf6ed950d277 100644 (file)
@@ -359,6 +359,10 @@ pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
     /// The caller must ensure that the slice outlives the pointer this
     /// function returns, or else it will end up pointing to garbage.
     ///
+    /// The caller must also ensure that the memory the pointer (non-transitively) points to
+    /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
+    /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
+    ///
     /// Modifying the container referenced by this slice may cause its buffer
     /// to be reallocated, which would also make any pointers to it invalid.
     ///
@@ -374,6 +378,8 @@ pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
     ///     }
     /// }
     /// ```
+    ///
+    /// [`as_mut_ptr`]: #method.as_mut_ptr
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub const fn as_ptr(&self) -> *const T {
@@ -3541,6 +3547,11 @@ fn size_hint(&self) -> (usize, Option<usize>) {
             (1, Some(self.v.len() + 1))
         }
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -3639,6 +3650,11 @@ fn size_hint(&self) -> (usize, Option<usize>) {
             (1, Some(self.v.len() + 1))
         }
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -3704,6 +3720,11 @@ fn next(&mut self) -> Option<&'a [T]> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
@@ -3768,6 +3789,11 @@ fn next(&mut self) -> Option<&'a mut [T]> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
index 45421848cec5db602f26a4b3cd4ecdf02290cd1f..0e8a2da3c110d70a413a0a8b9ae76909116a982a 100644 (file)
@@ -1333,6 +1333,11 @@ fn next(&mut self) -> Option<&'a str> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.0.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1379,6 +1384,11 @@ fn next(&mut self) -> Option<&'a str> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.0.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2188,7 +2198,11 @@ pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
     /// [`u8`]. This pointer will be pointing to the first byte of the string
     /// slice.
     ///
+    /// The caller must ensure that the returned pointer is never written to.
+    /// If you need to mutate the contents of the string slice, use [`as_mut_ptr`].
+    ///
     /// [`u8`]: primitive.u8.html
+    /// [`as_mut_ptr`]: #method.as_mut_ptr
     ///
     /// # Examples
     ///
@@ -4217,6 +4231,11 @@ fn next(&mut self) -> Option<&'a str> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "split_whitespace", since = "1.1.0")]
@@ -4243,6 +4262,11 @@ fn next(&mut self) -> Option<&'a str> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
index 025f7fb5cc6c31e747908d10e80993e9a1c360eb..b8075ef2942e083d67d7af6f5778b68fcb7b648a 100644 (file)
@@ -31,7 +31,7 @@
 #![feature(slice_partition_dedup)]
 #![feature(copy_within)]
 #![feature(int_error_matching)]
-#![deny(rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
 extern crate test;
 
index 4c527f80d0f5d7593401c2891cfdeda08b08b8fa..b199eee6dad87a2285f099fac8a22274264fdedb 100644 (file)
@@ -12,6 +12,7 @@
 use crate::hir::def_id::DefId;
 use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use std::fmt::{self, Display};
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 #[derive(Copy, Clone, PartialEq)]
@@ -95,18 +96,18 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
     fn check_attributes(&self, item: &hir::Item, target: Target) {
         if target == Target::Fn || target == Target::Const {
             self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id_from_hir_id(item.hir_id));
-        } else if let Some(a) = item.attrs.iter().find(|a| a.check_name("target_feature")) {
+        } else if let Some(a) = item.attrs.iter().find(|a| a.check_name(sym::target_feature)) {
             self.tcx.sess.struct_span_err(a.span, "attribute should be applied to a function")
                 .span_label(item.span, "not a function")
                 .emit();
         }
 
         for attr in &item.attrs {
-            if attr.check_name("inline") {
+            if attr.check_name(sym::inline) {
                 self.check_inline(attr, &item.span, target)
-            } else if attr.check_name("non_exhaustive") {
+            } else if attr.check_name(sym::non_exhaustive) {
                 self.check_non_exhaustive(attr, item, target)
-            } else if attr.check_name("marker") {
+            } else if attr.check_name(sym::marker) {
                 self.check_marker(attr, item, target)
             }
         }
@@ -166,7 +167,7 @@ fn check_repr(&self, item: &hir::Item, target: Target) {
         // ```
         let hints: Vec<_> = item.attrs
             .iter()
-            .filter(|attr| attr.check_name("repr"))
+            .filter(|attr| attr.check_name(sym::repr))
             .filter_map(|attr| attr.meta_item_list())
             .flatten()
             .collect();
@@ -177,9 +178,9 @@ fn check_repr(&self, item: &hir::Item, target: Target) {
         let mut is_transparent = false;
 
         for hint in &hints {
-            let (article, allowed_targets) = match hint.name_or_empty().get() {
-                name @ "C" | name @ "align" => {
-                    is_c |= name == "C";
+            let (article, allowed_targets) = match hint.name_or_empty() {
+                name @ sym::C | name @ sym::align => {
+                    is_c |= name == sym::C;
                     if target != Target::Struct &&
                             target != Target::Union &&
                             target != Target::Enum {
@@ -188,7 +189,7 @@ fn check_repr(&self, item: &hir::Item, target: Target) {
                         continue
                     }
                 }
-                "packed" => {
+                sym::packed => {
                     if target != Target::Struct &&
                             target != Target::Union {
                                 ("a", "struct or union")
@@ -196,7 +197,7 @@ fn check_repr(&self, item: &hir::Item, target: Target) {
                         continue
                     }
                 }
-                "simd" => {
+                sym::simd => {
                     is_simd = true;
                     if target != Target::Struct {
                         ("a", "struct")
@@ -204,7 +205,7 @@ fn check_repr(&self, item: &hir::Item, target: Target) {
                         continue
                     }
                 }
-                "transparent" => {
+                sym::transparent => {
                     is_transparent = true;
                     if target != Target::Struct {
                         ("a", "struct")
@@ -212,9 +213,9 @@ fn check_repr(&self, item: &hir::Item, target: Target) {
                         continue
                     }
                 }
-                "i8"  | "u8"  | "i16" | "u16" |
-                "i32" | "u32" | "i64" | "u64" |
-                "isize" | "usize" => {
+                sym::i8  | sym::u8  | sym::i16 | sym::u16 |
+                sym::i32 | sym::u32 | sym::i64 | sym::u64 |
+                sym::isize | sym::usize => {
                     int_reprs += 1;
                     if target != Target::Enum {
                         ("an", "enum")
@@ -268,10 +269,10 @@ fn check_stmt_attributes(&self, stmt: &hir::Stmt) {
         // When checking statements ignore expressions, they will be checked later
         if let hir::StmtKind::Local(ref l) = stmt.node {
             for attr in l.attrs.iter() {
-                if attr.check_name("inline") {
+                if attr.check_name(sym::inline) {
                     self.check_inline(attr, &stmt.span, Target::Statement);
                 }
-                if attr.check_name("repr") {
+                if attr.check_name(sym::repr) {
                     self.emit_repr_error(
                         attr.span,
                         stmt.span,
@@ -289,10 +290,10 @@ fn check_expr_attributes(&self, expr: &hir::Expr) {
             _ => Target::Expression,
         };
         for attr in expr.attrs.iter() {
-            if attr.check_name("inline") {
+            if attr.check_name(sym::inline) {
                 self.check_inline(attr, &expr.span, target);
             }
-            if attr.check_name("repr") {
+            if attr.check_name(sym::repr) {
                 self.emit_repr_error(
                     attr.span,
                     expr.span,
@@ -305,7 +306,7 @@ fn check_expr_attributes(&self, expr: &hir::Expr) {
 
     fn check_used(&self, item: &hir::Item, target: Target) {
         for attr in &item.attrs {
-            if attr.check_name("used") && target != Target::Static {
+            if attr.check_name(sym::used) && target != Target::Static {
                 self.tcx.sess
                     .span_err(attr.span, "attribute must be applied to a `static` variable");
             }
index 1612e0a6e9df3dd19bfb6acd6011226730fb3886..dd0d13d8f5a6aea74ae0498538285a36463d4209 100644 (file)
@@ -64,7 +64,7 @@
 use syntax::source_map::{respan, CompilerDesugaringKind, Spanned};
 use syntax::source_map::CompilerDesugaringKind::IfTemporary;
 use syntax::std_inject;
-use syntax::symbol::{keywords, Symbol};
+use syntax::symbol::{keywords, Symbol, sym};
 use syntax::tokenstream::{TokenStream, TokenTree};
 use syntax::parse::token::Token;
 use syntax::visit::{self, Visitor};
@@ -73,7 +73,7 @@
 const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
 
 pub struct LoweringContext<'a> {
-    crate_root: Option<&'static str>,
+    crate_root: Option<Symbol>,
 
     /// Used to assign ids to HIR nodes that do not directly correspond to an AST node.
     sess: &'a Session,
@@ -164,8 +164,8 @@ fn resolve_hir_path(
     fn resolve_str_path(
         &mut self,
         span: Span,
-        crate_root: Option<&str>,
-        components: &[&str],
+        crate_root: Option<Symbol>,
+        components: &[Symbol],
         is_value: bool,
     ) -> hir::Path;
 }
@@ -228,7 +228,7 @@ pub fn lower_crate(
     dep_graph.assert_ignored();
 
     LoweringContext {
-        crate_root: std_inject::injected_crate_name(),
+        crate_root: std_inject::injected_crate_name().map(Symbol::intern),
         sess,
         cstore,
         resolver,
@@ -1149,7 +1149,7 @@ fn make_async_expr(
             ].into()),
         );
         let gen_future = self.expr_std_path(
-            unstable_span, &["future", "from_generator"], None, ThinVec::new());
+            unstable_span, &[sym::future, sym::from_generator], None, ThinVec::new());
         hir::ExprKind::Call(P(gen_future), hir_vec![generator])
     }
 
@@ -2548,7 +2548,7 @@ fn lower_async_fn_output_type_to_future_bound(
 
         // ::std::future::Future<future_params>
         let future_path =
-            self.std_path(span, &["future", "Future"], Some(future_params), false);
+            self.std_path(span, &[sym::future, sym::Future], Some(future_params), false);
 
         hir::GenericBound::Trait(
             hir::PolyTraitRef {
@@ -2727,7 +2727,7 @@ fn lower_generic_param(&mut self,
                         self.lower_ty(x, ImplTraitContext::disallowed())
                     }),
                     synthetic: param.attrs.iter()
-                                          .filter(|attr| attr.check_name("rustc_synthetic"))
+                                          .filter(|attr| attr.check_name(sym::rustc_synthetic))
                                           .map(|_| hir::SyntheticTyParamKind::ImplTrait)
                                           .next(),
                 };
@@ -2745,7 +2745,7 @@ fn lower_generic_param(&mut self,
             hir_id: self.lower_node_id(param.id),
             name,
             span: param.ident.span,
-            pure_wrt_drop: attr::contains_name(&param.attrs, "may_dangle"),
+            pure_wrt_drop: attr::contains_name(&param.attrs, sym::may_dangle),
             attrs: self.lower_attrs(&param.attrs),
             bounds,
             kind,
@@ -3773,8 +3773,8 @@ pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
         let mut vis = self.lower_visibility(&i.vis, None);
         let attrs = self.lower_attrs(&i.attrs);
         if let ItemKind::MacroDef(ref def) = i.node {
-            if !def.legacy || attr::contains_name(&i.attrs, "macro_export") ||
-                              attr::contains_name(&i.attrs, "rustc_doc_only_macro") {
+            if !def.legacy || attr::contains_name(&i.attrs, sym::macro_export) ||
+                              attr::contains_name(&i.attrs, sym::rustc_doc_only_macro) {
                 let body = self.lower_token_stream(def.stream());
                 let hir_id = self.lower_node_id(i.id);
                 self.exported_macros.push(hir::MacroDef {
@@ -4100,7 +4100,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let ohs = P(self.lower_expr(ohs));
                 hir::ExprKind::Unary(op, ohs)
             }
-            ExprKind::Lit(ref l) => hir::ExprKind::Lit((*l).clone()),
+            ExprKind::Lit(ref l) => hir::ExprKind::Lit(respan(l.span, l.node.clone())),
             ExprKind::Cast(ref expr, ref ty) => {
                 let expr = P(self.lower_expr(expr));
                 hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
@@ -4194,7 +4194,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                         |x: P<hir::Expr>| x.into_inner(),
                     );
                     block.expr = Some(this.wrap_in_try_constructor(
-                        "from_ok", tail, unstable_span));
+                        sym::from_ok, tail, unstable_span));
                     hir::ExprKind::Block(P(block), None)
                 })
             }
@@ -4336,7 +4336,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 self.expr_call_std_assoc_fn(
                     id,
                     e.span,
-                    &["ops", "RangeInclusive"],
+                    &[sym::ops, sym::RangeInclusive],
                     "new",
                     hir_vec![e1, e2],
                 )
@@ -4345,11 +4345,11 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 use syntax::ast::RangeLimits::*;
 
                 let path = match (e1, e2, lims) {
-                    (&None, &None, HalfOpen) => "RangeFull",
-                    (&Some(..), &None, HalfOpen) => "RangeFrom",
-                    (&None, &Some(..), HalfOpen) => "RangeTo",
-                    (&Some(..), &Some(..), HalfOpen) => "Range",
-                    (&None, &Some(..), Closed) => "RangeToInclusive",
+                    (&None, &None, HalfOpen) => sym::RangeFull,
+                    (&Some(..), &None, HalfOpen) => sym::RangeFrom,
+                    (&None, &Some(..), HalfOpen) => sym::RangeTo,
+                    (&Some(..), &Some(..), HalfOpen) => sym::Range,
+                    (&None, &Some(..), Closed) => sym::RangeToInclusive,
                     (&Some(..), &Some(..), Closed) => unreachable!(),
                     (_, &None, Closed) => self.diagnostic()
                         .span_fatal(e.span, "inclusive range with no end")
@@ -4367,7 +4367,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     .collect::<P<[hir::Field]>>();
 
                 let is_unit = fields.is_empty();
-                let struct_path = ["ops", path];
+                let struct_path = [sym::ops, path];
                 let struct_path = self.std_path(e.span, &struct_path, None, is_unit);
                 let struct_path = hir::QPath::Resolved(None, P(struct_path));
 
@@ -4656,7 +4656,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let match_expr = {
                     let iter = P(self.expr_ident(head_sp, iter, iter_pat_nid));
                     let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
-                    let next_path = &["iter", "Iterator", "next"];
+                    let next_path = &[sym::iter, sym::Iterator, sym::next];
                     let next_expr = P(self.expr_call_std_path(
                         head_sp,
                         next_path,
@@ -4723,7 +4723,8 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
 
                 // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
                 let into_iter_expr = {
-                    let into_iter_path = &["iter", "IntoIterator", "into_iter"];
+                    let into_iter_path =
+                        &[sym::iter, sym::IntoIterator, sym::into_iter];
                     P(self.expr_call_std_path(
                         head_sp,
                         into_iter_path,
@@ -4780,7 +4781,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     // expand <expr>
                     let sub_expr = self.lower_expr(sub_expr);
 
-                    let path = &["ops", "Try", "into_result"];
+                    let path = &[sym::ops, sym::Try, sym::into_result];
                     P(self.expr_call_std_path(
                         unstable_span,
                         path,
@@ -4822,12 +4823,12 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     let err_ident = self.str_to_ident("err");
                     let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
                     let from_expr = {
-                        let from_path = &["convert", "From", "from"];
+                        let from_path = &[sym::convert, sym::From, sym::from];
                         let err_expr = self.expr_ident(try_span, err_ident, err_local_nid);
                         self.expr_call_std_path(try_span, from_path, hir_vec![err_expr])
                     };
                     let from_err_expr =
-                        self.wrap_in_try_constructor("from_error", from_expr, unstable_span);
+                        self.wrap_in_try_constructor(sym::from_error, from_expr, unstable_span);
                     let thin_attrs = ThinVec::from(attrs);
                     let catch_scope = self.catch_scopes.last().map(|x| *x);
                     let ret_expr = if let Some(catch_node) = catch_scope {
@@ -5057,7 +5058,7 @@ fn expr_call(
     fn expr_call_std_path(
         &mut self,
         span: Span,
-        path_components: &[&str],
+        path_components: &[Symbol],
         args: hir::HirVec<hir::Expr>,
     ) -> hir::Expr {
         let path = P(self.expr_std_path(span, path_components, None, ThinVec::new()));
@@ -5077,7 +5078,7 @@ fn expr_call_std_assoc_fn(
         &mut self,
         ty_path_id: hir::HirId,
         span: Span,
-        ty_path_components: &[&str],
+        ty_path_components: &[Symbol],
         assoc_fn_name: &str,
         args: hir::HirVec<hir::Expr>,
     ) -> hir::ExprKind {
@@ -5119,7 +5120,7 @@ fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>) -> hir::Expr {
     fn expr_std_path(
         &mut self,
         span: Span,
-        components: &[&str],
+        components: &[Symbol],
         params: Option<P<hir::GenericArgs>>,
         attrs: ThinVec<Attribute>,
     ) -> hir::Expr {
@@ -5250,25 +5251,25 @@ fn pat_bool(&mut self, span: Span, val: bool) -> P<hir::Pat> {
     }
 
     fn pat_ok(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
-        self.pat_std_enum(span, &["result", "Result", "Ok"], hir_vec![pat])
+        self.pat_std_enum(span, &[sym::result, sym::Result, sym::Ok], hir_vec![pat])
     }
 
     fn pat_err(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
-        self.pat_std_enum(span, &["result", "Result", "Err"], hir_vec![pat])
+        self.pat_std_enum(span, &[sym::result, sym::Result, sym::Err], hir_vec![pat])
     }
 
     fn pat_some(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
-        self.pat_std_enum(span, &["option", "Option", "Some"], hir_vec![pat])
+        self.pat_std_enum(span, &[sym::option, sym::Option, sym::Some], hir_vec![pat])
     }
 
     fn pat_none(&mut self, span: Span) -> P<hir::Pat> {
-        self.pat_std_enum(span, &["option", "Option", "None"], hir_vec![])
+        self.pat_std_enum(span, &[sym::option, sym::Option, sym::None], hir_vec![])
     }
 
     fn pat_std_enum(
         &mut self,
         span: Span,
-        components: &[&str],
+        components: &[Symbol],
         subpats: hir::HirVec<P<hir::Pat>>,
     ) -> P<hir::Pat> {
         let path = self.std_path(span, components, None, true);
@@ -5321,7 +5322,7 @@ fn pat(&mut self, span: Span, pat: hir::PatKind) -> P<hir::Pat> {
     fn std_path(
         &mut self,
         span: Span,
-        components: &[&str],
+        components: &[Symbol],
         params: Option<P<hir::GenericArgs>>,
         is_value: bool,
     ) -> hir::Path {
@@ -5520,11 +5521,11 @@ fn maybe_lint_bare_trait(&self, span: Span, id: NodeId, is_global: bool) {
 
     fn wrap_in_try_constructor(
         &mut self,
-        method: &'static str,
+        method: Symbol,
         e: hir::Expr,
         unstable_span: Span,
     ) -> P<hir::Expr> {
-        let path = &["ops", "Try", method];
+        let path = &[sym::ops, sym::Try, method];
         let from_err = P(self.expr_std_path(unstable_span, path, None,
                                             ThinVec::new()));
         P(self.expr_call(e.span, from_err, hir_vec![e]))
@@ -5594,7 +5595,7 @@ fn lower_await(
             let new_unchecked_expr_kind = self.expr_call_std_assoc_fn(
                 pin_ty_id,
                 span,
-                &["pin", "Pin"],
+                &[sym::pin, sym::Pin],
                 "new_unchecked",
                 hir_vec![ref_mut_pinned],
             );
@@ -5602,7 +5603,7 @@ fn lower_await(
             let unsafe_expr = self.expr_unsafe(new_unchecked);
             P(self.expr_call_std_path(
                 gen_future_span,
-                &["future", "poll_with_tls_context"],
+                &[sym::future, sym::poll_with_tls_context],
                 hir_vec![unsafe_expr],
             ))
         };
@@ -5616,7 +5617,7 @@ fn lower_await(
             let x_expr = P(self.expr_ident(span, x_ident, x_pat_hid));
             let ready_pat = self.pat_std_enum(
                 span,
-                &["task", "Poll", "Ready"],
+                &[sym::task, sym::Poll, sym::Ready],
                 hir_vec![x_pat],
             );
             let break_x = self.with_loop_scope(loop_node_id, |this| {
@@ -5633,7 +5634,7 @@ fn lower_await(
         let pending_arm = {
             let pending_pat = self.pat_std_enum(
                 span,
-                &["task", "Poll", "Pending"],
+                &[sym::task, sym::Poll, sym::Pending],
                 hir_vec![],
             );
             let empty_block = P(self.expr_block_empty(span));
index 1a48dff213b5ff51cc8012e8a5d98493d747e920..b8ee98551a20e758f4b025f7fc54167a87bd2309 100644 (file)
@@ -1146,7 +1146,7 @@ fn suffix_matches(&self, parent: HirId) -> bool {
                 None => return false,
                 Some((node_id, name)) => (node_id, name),
             };
-            if mod_name != &**part {
+            if mod_name.as_str() != *part {
                 return false;
             }
             cursor = self.map.get_parent_item(mod_id);
@@ -1183,7 +1183,7 @@ fn item_is_mod(item: &Item) -> bool {
     // 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: HirId, name: Name) -> bool {
-        name == &**self.item_name && self.suffix_matches(parent_of_n)
+        name.as_str() == *self.item_name && self.suffix_matches(parent_of_n)
     }
 
     fn matches_suffix(&self, hir: HirId) -> bool {
index 9f7fa6c5557ef80436e18f6996fa7068e114b16f..f407be4e87b828390db961551aa7d19e24607e1d 100644 (file)
@@ -20,7 +20,7 @@
 use syntax::source_map::Spanned;
 use rustc_target::spec::abi::Abi;
 use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
-use syntax::ast::{Attribute, Label, Lit, StrStyle, FloatTy, IntTy, UintTy};
+use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
 use syntax::attr::{InlineAttr, OptimizeAttr};
 use syntax::ext::hygiene::SyntaxContext;
 use syntax::ptr::P;
@@ -126,12 +126,12 @@ mod item_local_id_inner {
     use rustc_macros::HashStable;
     newtype_index! {
         /// An `ItemLocalId` uniquely identifies something within a given "item-like",
-        /// that is within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no
+        /// that is, within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no
         /// guarantee that the numerical value of a given `ItemLocalId` corresponds to
         /// the node's position within the owning item in any way, but there is a
         /// guarantee that the `LocalItemId`s within an owner occupy a dense range of
         /// integers starting at zero, so a mapping that maps all or most nodes within
-        /// an "item-like" to something else can be implement by a `Vec` instead of a
+        /// an "item-like" to something else can be implemented by a `Vec` instead of a
         /// tree or hash map.
         pub struct ItemLocalId {
             derive [HashStable]
@@ -1331,6 +1331,9 @@ pub fn is_fn_or_closure(self) -> bool {
     }
 }
 
+/// A literal.
+pub type Lit = Spanned<LitKind>;
+
 /// A constant (expression) that's not an item or associated item,
 /// but needs its own `DefId` for type-checking, const-eval, etc.
 /// These are usually found nested inside types (e.g., array lengths)
index c42d8f3cb3c36275f99845a3b9d4dccd1494ea30..8a9028e5443912471481ee6749b1065d4aadb7aa 100644 (file)
@@ -5,7 +5,7 @@
 use syntax::parse::lexer::comments;
 use syntax::print::pp::{self, Breaks};
 use syntax::print::pp::Breaks::{Consistent, Inconsistent};
-use syntax::print::pprust::PrintState;
+use syntax::print::pprust::{self, PrintState};
 use syntax::ptr::P;
 use syntax::symbol::keywords;
 use syntax::util::parser::{self, AssocOp, Fixity};
@@ -18,7 +18,6 @@
 use std::borrow::Cow;
 use std::cell::Cell;
 use std::io::{self, Write, Read};
-use std::iter::Peekable;
 use std::vec;
 
 pub enum AnnNode<'a> {
@@ -76,7 +75,6 @@ pub struct State<'a> {
     pub s: pp::Printer<'a>,
     cm: Option<&'a SourceMap>,
     comments: Option<Vec<comments::Comment>>,
-    literals: Peekable<vec::IntoIter<comments::Literal>>,
     cur_cmnt: usize,
     boxes: Vec<pp::Breaks>,
     ann: &'a (dyn PpAnn + 'a),
@@ -98,14 +96,6 @@ fn comments(&mut self) -> &mut Option<Vec<comments::Comment>> {
     fn cur_cmnt(&mut self) -> &mut usize {
         &mut self.cur_cmnt
     }
-
-    fn cur_lit(&mut self) -> Option<&comments::Literal> {
-        self.literals.peek()
-    }
-
-    fn bump_lit(&mut self) -> Option<comments::Literal> {
-        self.literals.next()
-    }
 }
 
 #[allow(non_upper_case_globals)]
@@ -116,18 +106,16 @@ fn bump_lit(&mut self) -> Option<comments::Literal> {
 
 
 /// Requires you to pass an input filename and reader so that
-/// it can scan the input text for comments and literals to
-/// copy forward.
+/// it can scan the input text for comments to copy forward.
 pub fn print_crate<'a>(cm: &'a SourceMap,
                        sess: &ParseSess,
                        krate: &hir::Crate,
                        filename: FileName,
                        input: &mut dyn Read,
                        out: Box<dyn Write + 'a>,
-                       ann: &'a dyn PpAnn,
-                       is_expanded: bool)
+                       ann: &'a dyn PpAnn)
                        -> io::Result<()> {
-    let mut s = State::new_from_input(cm, sess, filename, input, out, ann, is_expanded);
+    let mut s = State::new_from_input(cm, sess, filename, input, out, ann);
 
     // When printing the AST, we sometimes need to inject `#[no_std]` here.
     // Since you can't compile the HIR, it's not necessary.
@@ -143,36 +131,21 @@ pub fn new_from_input(cm: &'a SourceMap,
                           filename: FileName,
                           input: &mut dyn Read,
                           out: Box<dyn Write + 'a>,
-                          ann: &'a dyn PpAnn,
-                          is_expanded: bool)
+                          ann: &'a dyn PpAnn)
                           -> State<'a> {
-        let (cmnts, lits) = comments::gather_comments_and_literals(sess, filename, input);
-
-        State::new(cm,
-                   out,
-                   ann,
-                   Some(cmnts),
-                   // If the code is post expansion, don't use the table of
-                   // literals, since it doesn't correspond with the literals
-                   // in the AST anymore.
-                   if is_expanded {
-                       None
-                   } else {
-                       Some(lits)
-                   })
+        let comments = comments::gather_comments(sess, filename, input);
+        State::new(cm, out, ann, Some(comments))
     }
 
     pub fn new(cm: &'a SourceMap,
                out: Box<dyn Write + 'a>,
                ann: &'a dyn PpAnn,
-               comments: Option<Vec<comments::Comment>>,
-               literals: Option<Vec<comments::Literal>>)
+               comments: Option<Vec<comments::Comment>>)
                -> State<'a> {
         State {
             s: pp::mk_printer(out, default_columns),
             cm: Some(cm),
             comments,
-            literals: literals.unwrap_or_default().into_iter().peekable(),
             cur_cmnt: 0,
             boxes: Vec::new(),
             ann,
@@ -189,7 +162,6 @@ pub fn to_string<F>(ann: &dyn PpAnn, f: F) -> String
             s: pp::mk_printer(Box::new(&mut wr), default_columns),
             cm: None,
             comments: None,
-            literals: vec![].into_iter().peekable(),
             cur_cmnt: 0,
             boxes: Vec::new(),
             ann,
@@ -646,7 +618,6 @@ pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
 
                 self.print_where_clause(&exist.generics.where_clause)?;
                 self.s.space()?;
-                self.word_space(":")?;
                 let mut real_bounds = Vec::with_capacity(exist.bounds.len());
                 for b in exist.bounds.iter() {
                     if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
@@ -1276,6 +1247,12 @@ fn print_expr_addr_of(&mut self,
         self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
     }
 
+    fn print_literal(&mut self, lit: &hir::Lit) -> io::Result<()> {
+        self.maybe_print_comment(lit.span.lo())?;
+        let (token, suffix) = lit.node.to_lit_token();
+        self.writer().word(pprust::literal_to_string(token, suffix))
+    }
+
     pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
         self.maybe_print_comment(expr.span.lo())?;
         self.print_outer_attributes(&expr.attrs)?;
index 6da2cb9ab57ea48155064cc4605c430c304708ae..8be610e8bf7af715691b4dd36bcd7fe1f432af6f 100644 (file)
@@ -28,7 +28,7 @@
 
 fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
     debug_assert!(ich::IGNORED_ATTRIBUTES.len() > 0);
-    ich::IGNORED_ATTRIBUTES.iter().map(|&s| Symbol::intern(s)).collect()
+    ich::IGNORED_ATTRIBUTES.iter().map(|&s| s).collect()
 }
 
 /// This is the context state available during incr. comp. hashing. It contains
index 35df43ef25efa4720ac28ea6e0ca7919d7a49a70..4e5718cc5ef2a275e5057e0c42097ba040b80548 100644 (file)
@@ -162,7 +162,13 @@ fn hash_stable<W: StableHasherResult>(&self,
     Unsuffixed
 });
 
-impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
+impl_stable_hash_for!(struct ::syntax::ast::Lit {
+    node,
+    token,
+    suffix,
+    span
+});
+
 impl_stable_hash_for!(enum ::syntax::ast::LitKind {
     Str(value, style),
     Err(value),
@@ -175,6 +181,8 @@ fn hash_stable<W: StableHasherResult>(&self,
     Bool(value)
 });
 
+impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
+
 impl_stable_hash_for!(enum ::syntax::ast::IntTy { Isize, I8, I16, I32, I64, I128 });
 impl_stable_hash_for!(enum ::syntax::ast::UintTy { Usize, U8, U16, U32, U64, U128 });
 impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 });
@@ -280,6 +288,19 @@ fn hash_stable<W: StableHasherResult>(&self,
     }
 }
 
+impl_stable_hash_for!(enum token::Lit {
+    Bool(val),
+    Byte(val),
+    Char(val),
+    Err(val),
+    Integer(val),
+    Float(val),
+    Str_(val),
+    ByteStr(val),
+    StrRaw(val, n),
+    ByteStrRaw(val, n)
+});
+
 fn hash_token<'a, 'gcx, W: StableHasherResult>(
     token: &token::Token,
     hcx: &mut StableHashingContext<'a>,
@@ -327,22 +348,8 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>(
         token::Token::CloseDelim(delim_token) => {
             std_hash::Hash::hash(&delim_token, hasher);
         }
-        token::Token::Literal(ref lit, ref opt_name) => {
-            mem::discriminant(lit).hash_stable(hcx, hasher);
-            match *lit {
-                token::Lit::Byte(val) |
-                token::Lit::Char(val) |
-                token::Lit::Err(val) |
-                token::Lit::Integer(val) |
-                token::Lit::Float(val) |
-                token::Lit::Str_(val) |
-                token::Lit::ByteStr(val) => val.hash_stable(hcx, hasher),
-                token::Lit::StrRaw(val, n) |
-                token::Lit::ByteStrRaw(val, n) => {
-                    val.hash_stable(hcx, hasher);
-                    n.hash_stable(hcx, hasher);
-                }
-            };
+        token::Token::Literal(lit, opt_name) => {
+            lit.hash_stable(hcx, hasher);
             opt_name.hash_stable(hcx, hasher);
         }
 
index b407b75e68c9af4c6e307fc6ae2c3ff6ef80465f..f3fc7ec8fda1530b4d9fe6295e01ce1967c818d0 100644 (file)
@@ -4,6 +4,8 @@
 pub use self::caching_source_map_view::CachingSourceMapView;
 pub use self::hcx::{StableHashingContextProvider, StableHashingContext, NodeIdHashingMode,
                     hash_stable_trait_impls};
+use syntax::symbol::{Symbol, sym};
+
 mod caching_source_map_view;
 mod hcx;
 
 mod impls_ty;
 mod impls_syntax;
 
-pub const ATTR_DIRTY: &str = "rustc_dirty";
-pub const ATTR_CLEAN: &str = "rustc_clean";
-pub const ATTR_IF_THIS_CHANGED: &str = "rustc_if_this_changed";
-pub const ATTR_THEN_THIS_WOULD_NEED: &str = "rustc_then_this_would_need";
-pub const ATTR_PARTITION_REUSED: &str = "rustc_partition_reused";
-pub const ATTR_PARTITION_CODEGENED: &str = "rustc_partition_codegened";
-pub const ATTR_EXPECTED_CGU_REUSE: &str = "rustc_expected_cgu_reuse";
+pub const ATTR_DIRTY: Symbol = sym::rustc_dirty;
+pub const ATTR_CLEAN: Symbol = sym::rustc_clean;
+pub const ATTR_IF_THIS_CHANGED: Symbol = sym::rustc_if_this_changed;
+pub const ATTR_THEN_THIS_WOULD_NEED: Symbol = sym::rustc_then_this_would_need;
+pub const ATTR_PARTITION_REUSED: Symbol = sym::rustc_partition_reused;
+pub const ATTR_PARTITION_CODEGENED: Symbol = sym::rustc_partition_codegened;
+pub const ATTR_EXPECTED_CGU_REUSE: Symbol = sym::rustc_expected_cgu_reuse;
 
-pub const IGNORED_ATTRIBUTES: &[&str] = &[
-    "cfg",
+pub const IGNORED_ATTRIBUTES: &[Symbol] = &[
+    sym::cfg,
     ATTR_IF_THIS_CHANGED,
     ATTR_THEN_THIS_WOULD_NEED,
     ATTR_DIRTY,
index f85fd524a5d9bd7f35eafaaccb4d42d0fd62b717..4351f94df2f135db586d5b7f310eaac9bd3416b2 100644 (file)
@@ -284,18 +284,40 @@ pub fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
         debug!("constrain_opaque_type: def_id={:?}", def_id);
         debug!("constrain_opaque_type: opaque_defn={:#?}", opaque_defn);
 
+        let tcx = self.tcx;
+
         let concrete_ty = self.resolve_type_vars_if_possible(&opaque_defn.concrete_ty);
 
         debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty);
 
-        let abstract_type_generics = self.tcx.generics_of(def_id);
+        let abstract_type_generics = tcx.generics_of(def_id);
 
-        let span = self.tcx.def_span(def_id);
+        let span = tcx.def_span(def_id);
 
-        // If there are required region bounds, we can just skip
-        // ahead.  There will already be a registered region
-        // obligation related `concrete_ty` to those regions.
+        // If there are required region bounds, we can use them.
         if opaque_defn.has_required_region_bounds {
+            let predicates_of = tcx.predicates_of(def_id);
+            debug!(
+                "constrain_opaque_type: predicates: {:#?}",
+                predicates_of,
+            );
+            let bounds = predicates_of.instantiate(tcx, opaque_defn.substs);
+            debug!("constrain_opaque_type: bounds={:#?}", bounds);
+            let opaque_type = tcx.mk_opaque(def_id, opaque_defn.substs);
+
+            let required_region_bounds = tcx.required_region_bounds(
+                opaque_type,
+                bounds.predicates.clone(),
+            );
+            debug_assert!(!required_region_bounds.is_empty());
+
+            for region in required_region_bounds {
+                concrete_ty.visit_with(&mut OpaqueTypeOutlivesVisitor {
+                    infcx: self,
+                    least_region: region,
+                    span,
+                });
+            }
             return;
         }
 
@@ -371,7 +393,7 @@ pub fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
             }
         }
 
-        let least_region = least_region.unwrap_or(self.tcx.lifetimes.re_static);
+        let least_region = least_region.unwrap_or(tcx.lifetimes.re_static);
         debug!("constrain_opaque_types: least_region={:?}", least_region);
 
         concrete_ty.visit_with(&mut OpaqueTypeOutlivesVisitor {
@@ -589,10 +611,7 @@ fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
             ty::ReLateBound(..) |
 
             // ignore `'static`, as that can appear anywhere
-            ty::ReStatic |
-
-            // ignore `ReScope`, which may appear in impl Trait in bindings.
-            ty::ReScope(..) => return r,
+            ty::ReStatic => return r,
 
             _ => { }
         }
@@ -683,6 +702,23 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                 self.tcx.mk_closure(def_id, ty::ClosureSubsts { substs })
             }
 
+            ty::Generator(def_id, substs, movability) => {
+                let generics = self.tcx.generics_of(def_id);
+                let substs = self.tcx.mk_substs(substs.substs.iter().enumerate().map(
+                    |(index, &kind)| {
+                        if index < generics.parent_count {
+                            // Accommodate missing regions in the parent kinds...
+                            self.fold_kind_mapping_missing_regions_to_empty(kind)
+                        } else {
+                            // ...but not elsewhere.
+                            self.fold_kind_normally(kind)
+                        }
+                    },
+                ));
+
+                self.tcx.mk_generator(def_id, ty::GeneratorSubsts { substs }, movability)
+            }
+
             _ => ty.super_fold_with(self),
         }
     }
index 2e5bd8add0cdcb017c247f6b43f15640ab032be4..9c926dff325bfb5a270f090d283c43c656660d1e 100644 (file)
@@ -14,7 +14,7 @@
 use syntax::attr;
 use syntax::feature_gate;
 use syntax::source_map::MultiSpan;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 
 pub struct LintLevelSets {
     list: Vec<LintSet>,
@@ -194,7 +194,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
             struct_span_err!(sess, span, E0452, "malformed lint attribute")
         };
         for attr in attrs {
-            let level = match Level::from_str(&attr.name_or_empty()) {
+            let level = match Level::from_symbol(attr.name_or_empty()) {
                 None => continue,
                 Some(lvl) => lvl,
             };
@@ -221,7 +221,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                 match item.node {
                     ast::MetaItemKind::Word => {}  // actual lint names handled later
                     ast::MetaItemKind::NameValue(ref name_value) => {
-                        if item.path == "reason" {
+                        if item.path == sym::reason {
                             // found reason, reslice meta list to exclude it
                             metas = &metas[0..metas.len()-1];
                             // FIXME (#55112): issue unused-attributes lint if we thereby
@@ -230,7 +230,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                                 if !self.sess.features_untracked().lint_reasons {
                                     feature_gate::emit_feature_err(
                                         &self.sess.parse_sess,
-                                        "lint_reasons",
+                                        sym::lint_reasons,
                                         item.span,
                                         feature_gate::GateIssue::Language,
                                         "lint reasons are experimental"
@@ -261,7 +261,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                         let mut err = bad_attr(li.span());
                         if let Some(item) = li.meta_item() {
                             if let ast::MetaItemKind::NameValue(_) = item.node {
-                                if item.path == "reason" {
+                                if item.path == sym::reason {
                                     err.help("reason in lint attribute must come last");
                                 }
                             }
index 6613440ee7c9e52cbef0971c77f7646f35ab8b2c..68b65f9b4a1ccfa9c948d76a4f1b8310e209f9a3 100644 (file)
@@ -38,7 +38,7 @@
 use syntax::source_map::{MultiSpan, ExpnFormat};
 use syntax::early_buffered_lints::BufferedEarlyLintId;
 use syntax::edition::Edition;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::Span;
 
 pub use crate::lint::context::{LateContext, EarlyContext, LintContext, LintStore,
@@ -570,6 +570,17 @@ pub fn from_str(x: &str) -> Option<Level> {
             _ => None,
         }
     }
+
+    /// Converts a symbol to a level.
+    pub fn from_symbol(x: Symbol) -> Option<Level> {
+        match x {
+            sym::allow => Some(Allow),
+            sym::warn => Some(Warn),
+            sym::deny => Some(Deny),
+            sym::forbid => Some(Forbid),
+            _ => None,
+        }
+    }
 }
 
 /// How a lint level was set.
@@ -752,7 +763,7 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
 
 pub fn maybe_lint_level_root(tcx: TyCtxt<'_, '_, '_>, id: hir::HirId) -> bool {
     let attrs = tcx.hir().attrs_by_hir_id(id);
-    attrs.iter().any(|attr| Level::from_str(&attr.name_or_empty()).is_some())
+    attrs.iter().any(|attr| Level::from_symbol(attr.name_or_empty()).is_some())
 }
 
 fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)
index a0107ed0546ddd2209245caa06445a344084da69..2a9928567f4dcfa2fed79a3dd44afba6ed765089 100644 (file)
@@ -19,6 +19,7 @@
 
 use syntax::{ast, source_map};
 use syntax::attr;
+use syntax::symbol::sym;
 use syntax_pos;
 
 // Any local node that may call something in its body block should be
@@ -304,22 +305,22 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
 fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_, '_, '_>,
                                     id: hir::HirId,
                                     attrs: &[ast::Attribute]) -> bool {
-    if attr::contains_name(attrs, "lang") {
+    if attr::contains_name(attrs, sym::lang) {
         return true;
     }
 
     // Stable attribute for #[lang = "panic_impl"]
-    if attr::contains_name(attrs, "panic_handler") {
+    if attr::contains_name(attrs, sym::panic_handler) {
         return true;
     }
 
     // (To be) stable attribute for #[lang = "oom"]
-    if attr::contains_name(attrs, "alloc_error_handler") {
+    if attr::contains_name(attrs, sym::alloc_error_handler) {
         return true;
     }
 
     // Don't lint about global allocators
-    if attr::contains_name(attrs, "global_allocator") {
+    if attr::contains_name(attrs, sym::global_allocator) {
         return true;
     }
 
index df77033ebef3b5999d489a8dcc3ee6368a95364a..67db2ec2481566e512869beff6b1c6e48dee2b03 100644 (file)
@@ -4,6 +4,7 @@
 use crate::session::config::EntryFnType;
 use syntax::attr;
 use syntax::entry::EntryPointType;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 use crate::hir::{HirId, Item, ItemKind, ImplItem, TraitItem};
 use crate::hir::itemlikevisit::ItemLikeVisitor;
@@ -58,7 +59,7 @@ fn entry_fn(tcx: TyCtxt<'_, '_, '_>, cnum: CrateNum) -> Option<(DefId, EntryFnTy
     }
 
     // If the user wants no main function at all, then stop here.
-    if attr::contains_name(&tcx.hir().krate().attrs, "no_main") {
+    if attr::contains_name(&tcx.hir().krate().attrs, sym::no_main) {
         return None;
     }
 
@@ -81,11 +82,11 @@ fn entry_fn(tcx: TyCtxt<'_, '_, '_>, cnum: CrateNum) -> Option<(DefId, EntryFnTy
 fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType {
     match item.node {
         ItemKind::Fn(..) => {
-            if attr::contains_name(&item.attrs, "start") {
+            if attr::contains_name(&item.attrs, sym::start) {
                 EntryPointType::Start
-            } else if attr::contains_name(&item.attrs, "main") {
+            } else if attr::contains_name(&item.attrs, sym::main) {
                 EntryPointType::MainAttr
-            } else if item.ident.name == "main" {
+            } else if item.ident.name == sym::main {
                 if at_root {
                     // This is a top-level function so can be 'main'.
                     EntryPointType::MainNamed
index 0e283ca6b1cf15170e231ebc86fc1ad0b72723dc..103580a598fcd9cea61e1c2804894fc985bf3d46 100644 (file)
@@ -18,7 +18,7 @@
 use crate::util::nodemap::FxHashMap;
 
 use syntax::ast;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::Span;
 use rustc_macros::HashStable;
 use crate::hir::itemlikevisit::ItemLikeVisitor;
@@ -209,9 +209,9 @@ fn collect_item(&mut self, item_index: usize, item_def_id: DefId) {
 /// are also extracted out when found.
 pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
     attrs.iter().find_map(|attr| Some(match attr {
-        _ if attr.check_name("lang") => (attr.value_str()?, attr.span),
-        _ if attr.check_name("panic_handler") => (Symbol::intern("panic_impl"), attr.span),
-        _ if attr.check_name("alloc_error_handler") => (Symbol::intern("oom"), attr.span),
+        _ if attr.check_name(sym::lang) => (attr.value_str()?, attr.span),
+        _ if attr.check_name(sym::panic_handler) => (Symbol::intern("panic_impl"), attr.span),
+        _ if attr.check_name(sym::alloc_error_handler) => (Symbol::intern("oom"), attr.span),
         _ => return None,
     }))
 }
index e79ef8bfc6fb43f0a31af6cd8003d4d8140a5318..76934ddd69b1bb7d9efab259f58e669fba61a630 100644 (file)
@@ -8,7 +8,7 @@
 use crate::hir::intravisit::{self, NestedVisitorMap, Visitor};
 use syntax::symbol::Symbol;
 use syntax::ast::{Attribute, MetaItem, MetaItemKind};
-use syntax_pos::{Span, symbols};
+use syntax_pos::{Span, sym};
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use rustc_macros::HashStable;
 use errors::DiagnosticId;
@@ -51,7 +51,7 @@ fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LibFeatureCollector<'a, 'tcx> {
     }
 
     fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option<Symbol>, Span)> {
-        let stab_attrs = [symbols::stable, symbols::unstable, symbols::rustc_const_unstable];
+        let stab_attrs = [sym::stable, sym::unstable, sym::rustc_const_unstable];
 
         // Find a stability attribute (i.e., `#[stable (..)]`, `#[unstable (..)]`,
         // `#[rustc_const_unstable (..)]`).
@@ -65,9 +65,9 @@ fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option<Symbol>, Span)> {
                 for meta in metas {
                     if let Some(mi) = meta.meta_item() {
                         // Find the `feature = ".."` meta-item.
-                        match (mi.name_or_empty().get(), mi.value_str()) {
-                            ("feature", val) => feature = val,
-                            ("since", val) => since = val,
+                        match (mi.name_or_empty(), mi.value_str()) {
+                            (sym::feature, val) => feature = val,
+                            (sym::since, val) => since = val,
                             _ => {}
                         }
                     }
@@ -76,7 +76,7 @@ fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option<Symbol>, Span)> {
                     // This additional check for stability is to make sure we
                     // don't emit additional, irrelevant errors for malformed
                     // attributes.
-                    if *stab_attr != "stable" || since.is_some() {
+                    if *stab_attr != sym::stable || since.is_some() {
                         return Some((feature, since, attr.span));
                     }
                 }
index a142b220f31afcb9d885f62dc4557bf061b940bd..cb333b5b0cba23e808ed1d3f6257c5aaef1ac081 100644 (file)
 use std::rc::Rc;
 use syntax::ast::{self, NodeId};
 use syntax::ptr::P;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax_pos::Span;
 
 use crate::hir;
@@ -362,7 +362,7 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
     if let FnKind::Method(..) = fk {
         let parent = ir.tcx.hir().get_parent_item(id);
         if let Some(Node::Item(i)) = ir.tcx.hir().find_by_hir_id(parent) {
-            if i.attrs.iter().any(|a| a.check_name("automatically_derived")) {
+            if i.attrs.iter().any(|a| a.check_name(sym::automatically_derived)) {
                 return;
             }
         }
index 85c7f4379033625c2f1264bf714de62deca7be2c..c7f8cf684e6b16c28c56408e92bc55b1999da574 100644 (file)
@@ -72,6 +72,7 @@
 use crate::hir::pat_util::EnumerateAndAdjustIterator;
 use crate::hir;
 use syntax::ast::{self, Name};
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 use std::borrow::Cow;
@@ -714,7 +715,7 @@ pub fn cat_res(&self,
                 // they also cannot be moved out of.
                 let is_thread_local = self.tcx.get_attrs(def_id)[..]
                     .iter()
-                    .any(|attr| attr.check_name("thread_local"));
+                    .any(|attr| attr.check_name(sym::thread_local));
 
                 let cat = if is_thread_local {
                     let re = self.temporary_scope(hir_id.local_id);
index ea077220e0be37680a22a8957b0951a733ef94d7..5f355d17072b8705682073bd7377fdd681e26405 100644 (file)
@@ -7,15 +7,16 @@
 
 use crate::session::Session;
 use syntax::ast;
+use syntax::symbol::{Symbol, sym};
 
 use rustc_data_structures::sync::Once;
 
 pub fn update_limits(sess: &Session, krate: &ast::Crate) {
-    update_limit(krate, &sess.recursion_limit, "recursion_limit", 64);
-    update_limit(krate, &sess.type_length_limit, "type_length_limit", 1048576);
+    update_limit(krate, &sess.recursion_limit, sym::recursion_limit, 64);
+    update_limit(krate, &sess.type_length_limit, sym::type_length_limit, 1048576);
 }
 
-fn update_limit(krate: &ast::Crate, limit: &Once<usize>, name: &str, default: usize) {
+fn update_limit(krate: &ast::Crate, limit: &Once<usize>, name: Symbol, default: usize) {
     for attr in &krate.attrs {
         if !attr.check_name(name) {
             continue;
index d835d872d76d7f3be775fb8f970830cb83785d62..2402d0eefde4886e0bdc5e8e077a487753b58c8b 100644 (file)
@@ -23,7 +23,7 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::ptr::P;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax_pos::Span;
 
 use crate::hir::intravisit::{self, NestedVisitorMap, Visitor};
@@ -1285,7 +1285,7 @@ fn compute_object_lifetime_defaults(
                 let result = object_lifetime_defaults_for_item(tcx, generics);
 
                 // Debugging aid.
-                if attr::contains_name(&item.attrs, "rustc_object_lifetime_default") {
+                if attr::contains_name(&item.attrs, sym::rustc_object_lifetime_default) {
                     let object_lifetime_default_reprs: String = result
                         .iter()
                         .map(|set| match *set {
index 5078bd7c594235b11a25d86a4c3641f7162720ef..abcf164cda6d46f783eec9251c3311f79a9c73be 100644 (file)
@@ -11,7 +11,7 @@
 use crate::ty::query::Providers;
 use crate::middle::privacy::AccessLevels;
 use crate::session::{DiagnosticMessageId, Session};
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::{Span, MultiSpan};
 use syntax::ast::Attribute;
 use syntax::errors::Applicability;
@@ -195,7 +195,7 @@ fn annotate<F>(&mut self, hir_id: HirId, attrs: &[Attribute],
             // Emit errors for non-staged-api crates.
             for attr in attrs {
                 let name = attr.name_or_empty();
-                if ["unstable", "stable", "rustc_deprecated"].contains(&name.get()) {
+                if [sym::unstable, sym::stable, sym::rustc_deprecated].contains(&name) {
                     attr::mark_used(attr);
                     self.tcx.sess.span_err(attr.span, "stability attributes may not be used \
                                                         outside of the standard library");
@@ -669,7 +669,7 @@ pub fn eval_stability(self, def_id: DefId, id: Option<HirId>, span: Span) -> Eva
 
         match stability {
             Some(&Stability { level: attr::Unstable { reason, issue }, feature, .. }) => {
-                if span.allows_unstable(&feature.as_str()) {
+                if span.allows_unstable(feature) {
                     debug!("stability: skipping span={:?} since it is internal", span);
                     return EvalResult::Allow;
                 }
@@ -686,7 +686,7 @@ pub fn eval_stability(self, def_id: DefId, id: Option<HirId>, span: Span) -> Eva
                 // the `-Z force-unstable-if-unmarked` flag present (we're
                 // compiling a compiler crate), then let this missing feature
                 // annotation slide.
-                if feature == "rustc_private" && issue == 27812 {
+                if feature == sym::rustc_private && issue == 27812 {
                     if self.sess.opts.debugging_opts.force_unstable_if_unmarked {
                         return EvalResult::Allow;
                     }
@@ -739,7 +739,7 @@ pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) {
                 let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
                 let fresh = self.sess.one_time_diagnostics.borrow_mut().insert(error_id);
                 if fresh {
-                    emit_feature_err(&self.sess.parse_sess, &feature.as_str(), span,
+                    emit_feature_err(&self.sess.parse_sess, feature, span,
                                      GateIssue::Library(Some(issue)), &msg);
                 }
             }
@@ -802,13 +802,13 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
 
                 if adt_def.has_dtor(self.tcx) {
                     emit_feature_err(&self.tcx.sess.parse_sess,
-                                     "untagged_unions", item.span, GateIssue::Language,
+                                     sym::untagged_unions, item.span, GateIssue::Language,
                                      "unions with `Drop` implementations are unstable");
                 } else {
                     let param_env = self.tcx.param_env(def_id);
                     if !param_env.can_type_implement_copy(self.tcx, ty).is_ok() {
                         emit_feature_err(&self.tcx.sess.parse_sess,
-                                         "untagged_unions", item.span, GateIssue::Language,
+                                         sym::untagged_unions, item.span, GateIssue::Language,
                                          "unions with non-`Copy` fields are unstable");
                     }
                 }
index 312924e5e90f549418a5bc7565f383f0912a8fc4..75c21c738f7a07ae9e0da2de1d5ffcfa77c7d92f 100644 (file)
@@ -6,7 +6,7 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_target::spec::PanicStrategy;
 use syntax::ast;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::Span;
 use crate::hir::def_id::DefId;
 use crate::hir::intravisit::{Visitor, NestedVisitorMap};
@@ -46,8 +46,8 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
 pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
     lang_items::extract(attrs).and_then(|(name, _)| {
-        $(if name == stringify!($name) {
-            Some(Symbol::intern(stringify!($sym)))
+        $(if name == sym::$name {
+            Some(sym::$sym)
         } else)* {
             None
         }
index 0e7b66b744499d595d2812626b8bf0c8735f67d9..2fff4c3f109b103565cbcd910653252f57758d5e 100644 (file)
     }
 
     Other {
-        query target_features_whitelist(_: CrateNum) -> Lrc<FxHashMap<String, Option<String>>> {
+        query target_features_whitelist(_: CrateNum) -> Lrc<FxHashMap<String, Option<Symbol>>> {
             eval_always
             desc { "looking up the whitelist of target features" }
         }
index 12427daa38381d2baea1549380f2458bd9589754..f61ffac15d5f92acfa78a13f4c98bf69c054f26a 100644 (file)
@@ -2753,6 +2753,7 @@ fn test_switch_implies_cfg_test() {
     // another --cfg test
     #[test]
     fn test_switch_implies_cfg_test_unless_cfg_test() {
+        use syntax::symbol::sym;
         syntax::with_globals(|| {
             let matches = &match optgroups().parse(&["--test".to_string(),
                                                      "--cfg=test".to_string()]) {
@@ -2763,7 +2764,7 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
             let (sessopts, cfg) = build_session_options_and_crate_config(matches);
             let sess = build_session(sessopts, None, registry);
             let cfg = build_configuration(&sess, to_crate_config(cfg));
-            let mut test_items = cfg.iter().filter(|&&(name, _)| name == "test");
+            let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test);
             assert!(test_items.next().is_some());
             assert!(test_items.next().is_none());
         });
index e8c7965ab4f45835c196bdff7909b22b7d3ee480..4d47491661e8639fba50b6752de90e7eaa5bae4d 100644 (file)
@@ -29,6 +29,7 @@
 use syntax::json::JsonEmitter;
 use syntax::source_map;
 use syntax::parse::{self, ParseSess};
+use syntax::symbol::Symbol;
 use syntax_pos::{MultiSpan, Span};
 use crate::util::profiling::SelfProfiler;
 
@@ -86,7 +87,7 @@ pub struct Session {
     /// in order to avoid redundantly verbose output (Issue #24690, #44953).
     pub one_time_diagnostics: Lock<FxHashSet<(DiagnosticMessageId, Option<Span>, String)>>,
     pub plugin_llvm_passes: OneThread<RefCell<Vec<String>>>,
-    pub plugin_attributes: Lock<Vec<(String, AttributeType)>>,
+    pub plugin_attributes: Lock<Vec<(Symbol, AttributeType)>>,
     pub crate_types: Once<Vec<config::CrateType>>,
     pub dependency_formats: Once<dependency_format::Dependencies>,
     /// The crate_disambiguator is constructed out of all the `-C metadata`
index 35d8e2beef55787688c70612d9530b429ec36e66..afbce5a4f0a49170e83fd41347281b9eeca6e368 100644 (file)
@@ -4,17 +4,16 @@
 //! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
 //! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html
 
-use crate::infer::CombinedSnapshot;
+use crate::infer::{CombinedSnapshot, InferOk};
 use crate::hir::def_id::{DefId, LOCAL_CRATE};
-use syntax_pos::DUMMY_SP;
 use crate::traits::{self, Normalized, SelectionContext, Obligation, ObligationCause};
 use crate::traits::IntercrateMode;
 use crate::traits::select::IntercrateAmbiguityCause;
 use crate::ty::{self, Ty, TyCtxt};
 use crate::ty::fold::TypeFoldable;
 use crate::ty::subst::Subst;
-
-use crate::infer::{InferOk};
+use syntax::symbol::sym;
+use syntax_pos::DUMMY_SP;
 
 /// Whether we do the orphan check relative to this crate or
 /// to some remote crate.
@@ -233,7 +232,7 @@ pub fn trait_ref_is_knowable<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
 pub fn trait_ref_is_local_or_fundamental<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                                          trait_ref: ty::TraitRef<'tcx>)
                                                          -> bool {
-    trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, "fundamental")
+    trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, sym::fundamental)
 }
 
 pub enum OrphanCheckErr<'tcx> {
index d9ccbba69d5c09e61c11c63d7b996f6bb1a76e1d..df2688397102299ab0c1602a27fd53a27e714cea 100644 (file)
@@ -35,6 +35,7 @@
 use errors::{Applicability, DiagnosticBuilder};
 use std::fmt;
 use syntax::ast;
+use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnFormat};
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
@@ -329,7 +330,7 @@ fn impl_similar_to(&self,
             return None
         };
 
-        if tcx.has_attr(impl_def_id, "rustc_on_unimplemented") {
+        if tcx.has_attr(impl_def_id, sym::rustc_on_unimplemented) {
             Some(impl_def_id)
         } else {
             None
index 2b286ee1b97fb222948e28187d1ba277f0a4d0f2..7ba7429f465a6642604d307dc05bd0b30b40d3a1 100644 (file)
@@ -7,6 +7,7 @@
 
 use syntax::ast::{MetaItem, NestedMetaItem};
 use syntax::attr;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 use syntax_pos::symbol::LocalInternedString;
 
@@ -84,25 +85,25 @@ pub fn parse(tcx: TyCtxt<'a, 'gcx, 'tcx>,
         let mut note = None;
         let mut subcommands = vec![];
         for item in item_iter {
-            if item.check_name("message") && message.is_none() {
+            if item.check_name(sym::message) && message.is_none() {
                 if let Some(message_) = item.value_str() {
                     message = Some(OnUnimplementedFormatString::try_parse(
                         tcx, trait_def_id, message_.as_str(), span)?);
                     continue;
                 }
-            } else if item.check_name("label") && label.is_none() {
+            } else if item.check_name(sym::label) && label.is_none() {
                 if let Some(label_) = item.value_str() {
                     label = Some(OnUnimplementedFormatString::try_parse(
                         tcx, trait_def_id, label_.as_str(), span)?);
                     continue;
                 }
-            } else if item.check_name("note") && note.is_none() {
+            } else if item.check_name(sym::note) && note.is_none() {
                 if let Some(note_) = item.value_str() {
                     note = Some(OnUnimplementedFormatString::try_parse(
                         tcx, trait_def_id, note_.as_str(), span)?);
                     continue;
                 }
-            } else if item.check_name("on") && is_root &&
+            } else if item.check_name(sym::on) && is_root &&
                 message.is_none() && label.is_none() && note.is_none()
             {
                 if let Some(items) = item.meta_item_list() {
@@ -139,7 +140,7 @@ pub fn of_item(tcx: TyCtxt<'a, 'gcx, 'tcx>,
     {
         let attrs = tcx.get_attrs(impl_def_id);
 
-        let attr = if let Some(item) = attr::find_by_name(&attrs, "rustc_on_unimplemented") {
+        let attr = if let Some(item) = attr::find_by_name(&attrs, sym::rustc_on_unimplemented) {
             item
         } else {
             return Ok(None);
index b5232e828c4cd366496ff9703f35d5f0764c7a9f..f05a19372918edd3e1b062d59fbefd20730af8d8 100644 (file)
@@ -19,6 +19,7 @@
 use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
 use rustc_macros::HashStable;
 use syntax::ast::Ident;
+use syntax::symbol::sym;
 use crate::ty::subst::{Subst, InternalSubsts};
 use crate::ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt};
 use crate::ty::fold::{TypeFoldable, TypeFolder};
@@ -1318,9 +1319,9 @@ fn confirm_generator_candidate<'cx, 'gcx, 'tcx>(
                                             gen_sig)
         .map_bound(|(trait_ref, yield_ty, return_ty)| {
             let name = tcx.associated_item(obligation.predicate.item_def_id).ident.name;
-            let ty = if name == "Return" {
+            let ty = if name == sym::Return {
                 return_ty
-            } else if name == "Yield" {
+            } else if name == sym::Yield {
                 yield_ty
             } else {
                 bug!()
index d68e2be9ea0860ef2439c4d6b5c9ee7873f6ebd7..c4be85050dbc2a04b9a82ef2c70bc419458ca0c9 100644 (file)
@@ -43,6 +43,7 @@
 use rustc_data_structures::bit_set::GrowableBitSet;
 use rustc_data_structures::sync::Lock;
 use rustc_target::spec::abi::Abi;
+use std::cell::Cell;
 use std::cmp;
 use std::fmt::{self, Display};
 use std::iter;
@@ -153,6 +154,36 @@ struct TraitObligationStack<'prev, 'tcx: 'prev> {
     /// selection-context's freshener. Used to check for recursion.
     fresh_trait_ref: ty::PolyTraitRef<'tcx>,
 
+    /// Starts out as false -- if, during evaluation, we encounter a
+    /// cycle, then we will set this flag to true for all participants
+    /// in the cycle (apart from the "head" node). These participants
+    /// will then forego caching their results. This is not the most
+    /// efficient solution, but it addresses #60010. The problem we
+    /// are trying to prevent:
+    ///
+    /// - If you have `A: AutoTrait` requires `B: AutoTrait` and `C: NonAutoTrait`
+    /// - `B: AutoTrait` requires `A: AutoTrait` (coinductive cycle, ok)
+    /// - `C: NonAutoTrait` requires `A: AutoTrait` (non-coinductive cycle, not ok)
+    ///
+    /// you don't want to cache that `B: AutoTrait` or `A: AutoTrait`
+    /// is `EvaluatedToOk`; this is because they were only considered
+    /// ok on the premise that if `A: AutoTrait` held, but we indeed
+    /// encountered a problem (later on) with `A: AutoTrait. So we
+    /// currently set a flag on the stack node for `B: AutoTrait` (as
+    /// well as the second instance of `A: AutoTrait`) to supress
+    /// caching.
+    ///
+    /// This is a simple, targeted fix. A more-performant fix requires
+    /// deeper changes, but would permit more caching: we could
+    /// basically defer caching until we have fully evaluated the
+    /// tree, and then cache the entire tree at once. In any case, the
+    /// performance impact here shouldn't be so horrible: every time
+    /// this is hit, we do cache at least one trait, so we only
+    /// evaluate each member of a cycle up to N times, where N is the
+    /// length of the cycle. This means the performance impact is
+    /// bounded and we shouldn't have any terrible worst-cases.
+    in_cycle: Cell<bool>,
+
     previous: TraitObligationStackList<'prev, 'tcx>,
 }
 
@@ -840,8 +871,16 @@ fn evaluate_trait_predicate_recursively<'o>(
         let (result, dep_node) = self.in_task(|this| this.evaluate_stack(&stack));
         let result = result?;
 
-        debug!("CACHE MISS: EVAL({:?})={:?}", fresh_trait_ref, result);
-        self.insert_evaluation_cache(obligation.param_env, fresh_trait_ref, dep_node, result);
+        if !stack.in_cycle.get() {
+            debug!("CACHE MISS: EVAL({:?})={:?}", fresh_trait_ref, result);
+            self.insert_evaluation_cache(obligation.param_env, fresh_trait_ref, dep_node, result);
+        } else {
+            debug!(
+                "evaluate_trait_predicate_recursively: skipping cache because {:?} \
+                 is a cycle participant",
+                fresh_trait_ref,
+            );
+        }
 
         Ok(result)
     }
@@ -948,6 +987,17 @@ fn evaluate_stack<'o>(
         {
             debug!("evaluate_stack({:?}) --> recursive", stack.fresh_trait_ref);
 
+            // If we have a stack like `A B C D E A`, where the top of
+            // the stack is the final `A`, then this will iterate over
+            // `A, E, D, C, B` -- i.e., all the participants apart
+            // from the cycle head. We mark them as participating in a
+            // cycle. This suppresses caching for those nodes. See
+            // `in_cycle` field for more details.
+            for item in stack.iter().take(rec_index + 1) {
+                debug!("evaluate_stack: marking {:?} as cycle participant", item.fresh_trait_ref);
+                item.in_cycle.set(true);
+            }
+
             // Subtle: when checking for a coinductive cycle, we do
             // not compare using the "freshened trait refs" (which
             // have erased regions) but rather the fully explicit
@@ -3690,6 +3740,7 @@ fn push_stack<'o, 's: 'o>(
         TraitObligationStack {
             obligation,
             fresh_trait_ref,
+            in_cycle: Cell::new(false),
             previous: previous_stack,
         }
     }
index 15524ca6e930ce322cd74cd3ad9050688e7bea76..c9fee02f66bbdf19970bd270fddf25bbfda9bda0 100644 (file)
@@ -74,7 +74,7 @@
 use syntax::attr;
 use syntax::source_map::MultiSpan;
 use syntax::feature_gate;
-use syntax::symbol::{Symbol, keywords, InternedString};
+use syntax::symbol::{Symbol, keywords, InternedString, sym};
 use syntax_pos::Span;
 
 use crate::hir;
@@ -1213,7 +1213,8 @@ pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u12
             }
             span_bug!(attr.span, "no arguments to `rustc_layout_scalar_valid_range` attribute");
         };
-        (get("rustc_layout_scalar_valid_range_start"), get("rustc_layout_scalar_valid_range_end"))
+        (get(sym::rustc_layout_scalar_valid_range_start),
+         get(sym::rustc_layout_scalar_valid_range_end))
     }
 
     pub fn lift<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lifted> {
@@ -3102,10 +3103,10 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
     };
     providers.is_panic_runtime = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
-        attr::contains_name(tcx.hir().krate_attrs(), "panic_runtime")
+        attr::contains_name(tcx.hir().krate_attrs(), sym::panic_runtime)
     };
     providers.is_compiler_builtins = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
-        attr::contains_name(tcx.hir().krate_attrs(), "compiler_builtins")
+        attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
     };
 }
index d1a8a9a34e1559fd57d3a72b80ed29ab2f717446..6d7b0926c7ae26527fbb131fbec4f251104bbc04 100644 (file)
                                            StableHasherResult};
 
 pub use rustc_target::abi::*;
+use rustc_target::spec::{HasTargetSpec, abi::Abi as SpecAbi};
+use rustc_target::abi::call::{
+    ArgAttribute, ArgAttributes, ArgType, Conv, FnType, IgnoreMode, PassMode, Reg, RegKind
+};
+
+
 
 pub trait IntegerExt {
     fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, signed: bool) -> Ty<'tcx>;
@@ -2259,3 +2265,380 @@ fn hash_stable<W: StableHasherResult>(&self,
         }
     }
 }
+
+pub trait FnTypeExt<'tcx, C>
+where
+    C: LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
+        + HasDataLayout
+        + HasTargetSpec
+        + HasTyCtxt<'tcx>
+        + HasParamEnv<'tcx>,
+{
+    fn of_instance(cx: &C, instance: &ty::Instance<'tcx>) -> Self;
+    fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self;
+    fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self;
+    fn new_internal(
+        cx: &C,
+        sig: ty::FnSig<'tcx>,
+        extra_args: &[Ty<'tcx>],
+        mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgType<'tcx, Ty<'tcx>>,
+    ) -> Self;
+    fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi);
+}
+
+impl<'tcx, C> FnTypeExt<'tcx, C> for call::FnType<'tcx, Ty<'tcx>>
+where
+    C: LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
+        + HasDataLayout
+        + HasTargetSpec
+        + HasTyCtxt<'tcx>
+        + HasParamEnv<'tcx>,
+{
+    fn of_instance(cx: &C, instance: &ty::Instance<'tcx>) -> Self {
+        let sig = instance.fn_sig(cx.tcx());
+        let sig = cx
+            .tcx()
+            .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
+        call::FnType::new(cx, sig, &[])
+    }
+
+    fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
+        call::FnType::new_internal(cx, sig, extra_args, |ty, _| ArgType::new(cx.layout_of(ty)))
+    }
+
+    fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
+        FnTypeExt::new_internal(cx, sig, extra_args, |ty, arg_idx| {
+            let mut layout = cx.layout_of(ty);
+            // Don't pass the vtable, it's not an argument of the virtual fn.
+            // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
+            // or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen
+            if arg_idx == Some(0) {
+                let fat_pointer_ty = if layout.is_unsized() {
+                    // unsized `self` is passed as a pointer to `self`
+                    // FIXME (mikeyhew) change this to use &own if it is ever added to the language
+                    cx.tcx().mk_mut_ptr(layout.ty)
+                } else {
+                    match layout.abi {
+                        Abi::ScalarPair(..) => (),
+                        _ => bug!("receiver type has unsupported layout: {:?}", layout),
+                    }
+
+                    // In the case of Rc<Self>, we need to explicitly pass a *mut RcBox<Self>
+                    // with a Scalar (not ScalarPair) ABI. This is a hack that is understood
+                    // elsewhere in the compiler as a method on a `dyn Trait`.
+                    // To get the type `*mut RcBox<Self>`, we just keep unwrapping newtypes until we
+                    // get a built-in pointer type
+                    let mut fat_pointer_layout = layout;
+                    'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr()
+                        && !fat_pointer_layout.ty.is_region_ptr()
+                    {
+                        'iter_fields: for i in 0..fat_pointer_layout.fields.count() {
+                            let field_layout = fat_pointer_layout.field(cx, i);
+
+                            if !field_layout.is_zst() {
+                                fat_pointer_layout = field_layout;
+                                continue 'descend_newtypes;
+                            }
+                        }
+
+                        bug!(
+                            "receiver has no non-zero-sized fields {:?}",
+                            fat_pointer_layout
+                        );
+                    }
+
+                    fat_pointer_layout.ty
+                };
+
+                // we now have a type like `*mut RcBox<dyn Trait>`
+                // change its layout to that of `*mut ()`, a thin pointer, but keep the same type
+                // this is understood as a special case elsewhere in the compiler
+                let unit_pointer_ty = cx.tcx().mk_mut_ptr(cx.tcx().mk_unit());
+                layout = cx.layout_of(unit_pointer_ty);
+                layout.ty = fat_pointer_ty;
+            }
+            ArgType::new(layout)
+        })
+    }
+
+    fn new_internal(
+        cx: &C,
+        sig: ty::FnSig<'tcx>,
+        extra_args: &[Ty<'tcx>],
+        mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgType<'tcx, Ty<'tcx>>,
+    ) -> Self {
+        debug!("FnType::new_internal({:?}, {:?})", sig, extra_args);
+
+        use rustc_target::spec::abi::Abi::*;
+        let conv = match cx.tcx().sess.target.target.adjust_abi(sig.abi) {
+            RustIntrinsic | PlatformIntrinsic | Rust | RustCall => Conv::C,
+
+            // It's the ABI's job to select this, not ours.
+            System => bug!("system abi should be selected elsewhere"),
+
+            Stdcall => Conv::X86Stdcall,
+            Fastcall => Conv::X86Fastcall,
+            Vectorcall => Conv::X86VectorCall,
+            Thiscall => Conv::X86ThisCall,
+            C => Conv::C,
+            Unadjusted => Conv::C,
+            Win64 => Conv::X86_64Win64,
+            SysV64 => Conv::X86_64SysV,
+            Aapcs => Conv::ArmAapcs,
+            PtxKernel => Conv::PtxKernel,
+            Msp430Interrupt => Conv::Msp430Intr,
+            X86Interrupt => Conv::X86Intr,
+            AmdGpuKernel => Conv::AmdGpuKernel,
+
+            // These API constants ought to be more specific...
+            Cdecl => Conv::C,
+        };
+
+        let mut inputs = sig.inputs();
+        let extra_args = if sig.abi == RustCall {
+            assert!(!sig.c_variadic && extra_args.is_empty());
+
+            match sig.inputs().last().unwrap().sty {
+                ty::Tuple(tupled_arguments) => {
+                    inputs = &sig.inputs()[0..sig.inputs().len() - 1];
+                    tupled_arguments.iter().map(|k| k.expect_ty()).collect()
+                }
+                _ => {
+                    bug!(
+                        "argument to function with \"rust-call\" ABI \
+                         is not a tuple"
+                    );
+                }
+            }
+        } else {
+            assert!(sig.c_variadic || extra_args.is_empty());
+            extra_args.to_vec()
+        };
+
+        let target = &cx.tcx().sess.target.target;
+        let win_x64_gnu =
+            target.target_os == "windows" && target.arch == "x86_64" && target.target_env == "gnu";
+        let linux_s390x =
+            target.target_os == "linux" && target.arch == "s390x" && target.target_env == "gnu";
+        let linux_sparc64 =
+            target.target_os == "linux" && target.arch == "sparc64" && target.target_env == "gnu";
+        let rust_abi = match sig.abi {
+            RustIntrinsic | PlatformIntrinsic | Rust | RustCall => true,
+            _ => false,
+        };
+
+        // Handle safe Rust thin and fat pointers.
+        let adjust_for_rust_scalar = |attrs: &mut ArgAttributes,
+                                      scalar: &Scalar,
+                                      layout: TyLayout<'tcx>,
+                                      offset: Size,
+                                      is_return: bool| {
+            // Booleans are always an i1 that needs to be zero-extended.
+            if scalar.is_bool() {
+                attrs.set(ArgAttribute::ZExt);
+                return;
+            }
+
+            // Only pointer types handled below.
+            if scalar.value != Pointer {
+                return;
+            }
+
+            if scalar.valid_range.start() < scalar.valid_range.end() {
+                if *scalar.valid_range.start() > 0 {
+                    attrs.set(ArgAttribute::NonNull);
+                }
+            }
+
+            if let Some(pointee) = layout.pointee_info_at(cx, offset) {
+                if let Some(kind) = pointee.safe {
+                    attrs.pointee_size = pointee.size;
+                    attrs.pointee_align = Some(pointee.align);
+
+                    // `Box` pointer parameters never alias because ownership is transferred
+                    // `&mut` pointer parameters never alias other parameters,
+                    // or mutable global data
+                    //
+                    // `&T` where `T` contains no `UnsafeCell<U>` is immutable,
+                    // and can be marked as both `readonly` and `noalias`, as
+                    // LLVM's definition of `noalias` is based solely on memory
+                    // dependencies rather than pointer equality
+                    let no_alias = match kind {
+                        PointerKind::Shared => false,
+                        PointerKind::UniqueOwned => true,
+                        PointerKind::Frozen | PointerKind::UniqueBorrowed => !is_return,
+                    };
+                    if no_alias {
+                        attrs.set(ArgAttribute::NoAlias);
+                    }
+
+                    if kind == PointerKind::Frozen && !is_return {
+                        attrs.set(ArgAttribute::ReadOnly);
+                    }
+                }
+            }
+        };
+
+        // Store the index of the last argument. This is useful for working with
+        // C-compatible variadic arguments.
+        let last_arg_idx = if sig.inputs().is_empty() {
+            None
+        } else {
+            Some(sig.inputs().len() - 1)
+        };
+
+        let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| {
+            let is_return = arg_idx.is_none();
+            let mut arg = mk_arg_type(ty, arg_idx);
+            if arg.layout.is_zst() {
+                // For some forsaken reason, x86_64-pc-windows-gnu
+                // doesn't ignore zero-sized struct arguments.
+                // The same is true for s390x-unknown-linux-gnu
+                // and sparc64-unknown-linux-gnu.
+                if is_return || rust_abi || (!win_x64_gnu && !linux_s390x && !linux_sparc64) {
+                    arg.mode = PassMode::Ignore(IgnoreMode::Zst);
+                }
+            }
+
+            // If this is a C-variadic function, this is not the return value,
+            // and there is one or more fixed arguments; ensure that the `VaList`
+            // is ignored as an argument.
+            if sig.c_variadic {
+                match (last_arg_idx, arg_idx) {
+                    (Some(last_idx), Some(cur_idx)) if last_idx == cur_idx => {
+                        let va_list_did = match cx.tcx().lang_items().va_list() {
+                            Some(did) => did,
+                            None => bug!("`va_list` lang item required for C-variadic functions"),
+                        };
+                        match ty.sty {
+                            ty::Adt(def, _) if def.did == va_list_did => {
+                                // This is the "spoofed" `VaList`. Set the arguments mode
+                                // so that it will be ignored.
+                                arg.mode = PassMode::Ignore(IgnoreMode::CVarArgs);
+                            }
+                            _ => (),
+                        }
+                    }
+                    _ => {}
+                }
+            }
+
+            // FIXME(eddyb) other ABIs don't have logic for scalar pairs.
+            if !is_return && rust_abi {
+                if let Abi::ScalarPair(ref a, ref b) = arg.layout.abi {
+                    let mut a_attrs = ArgAttributes::new();
+                    let mut b_attrs = ArgAttributes::new();
+                    adjust_for_rust_scalar(&mut a_attrs, a, arg.layout, Size::ZERO, false);
+                    adjust_for_rust_scalar(
+                        &mut b_attrs,
+                        b,
+                        arg.layout,
+                        a.value.size(cx).align_to(b.value.align(cx).abi),
+                        false,
+                    );
+                    arg.mode = PassMode::Pair(a_attrs, b_attrs);
+                    return arg;
+                }
+            }
+
+            if let Abi::Scalar(ref scalar) = arg.layout.abi {
+                if let PassMode::Direct(ref mut attrs) = arg.mode {
+                    adjust_for_rust_scalar(attrs, scalar, arg.layout, Size::ZERO, is_return);
+                }
+            }
+
+            arg
+        };
+
+        let mut fn_ty = FnType {
+            ret: arg_of(sig.output(), None),
+            args: inputs
+                .iter()
+                .cloned()
+                .chain(extra_args)
+                .enumerate()
+                .map(|(i, ty)| arg_of(ty, Some(i)))
+                .collect(),
+            c_variadic: sig.c_variadic,
+            conv,
+        };
+        fn_ty.adjust_for_abi(cx, sig.abi);
+        fn_ty
+    }
+
+    fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi) {
+        if abi == SpecAbi::Unadjusted {
+            return;
+        }
+
+        if abi == SpecAbi::Rust
+            || abi == SpecAbi::RustCall
+            || abi == SpecAbi::RustIntrinsic
+            || abi == SpecAbi::PlatformIntrinsic
+        {
+            let fixup = |arg: &mut ArgType<'tcx, Ty<'tcx>>| {
+                if arg.is_ignore() {
+                    return;
+                }
+
+                match arg.layout.abi {
+                    Abi::Aggregate { .. } => {}
+
+                    // This is a fun case! The gist of what this is doing is
+                    // that we want callers and callees to always agree on the
+                    // ABI of how they pass SIMD arguments. If we were to *not*
+                    // make these arguments indirect then they'd be immediates
+                    // in LLVM, which means that they'd used whatever the
+                    // appropriate ABI is for the callee and the caller. That
+                    // means, for example, if the caller doesn't have AVX
+                    // enabled but the callee does, then passing an AVX argument
+                    // across this boundary would cause corrupt data to show up.
+                    //
+                    // This problem is fixed by unconditionally passing SIMD
+                    // arguments through memory between callers and callees
+                    // which should get them all to agree on ABI regardless of
+                    // target feature sets. Some more information about this
+                    // issue can be found in #44367.
+                    //
+                    // Note that the platform intrinsic ABI is exempt here as
+                    // that's how we connect up to LLVM and it's unstable
+                    // anyway, we control all calls to it in libstd.
+                    Abi::Vector { .. }
+                        if abi != SpecAbi::PlatformIntrinsic
+                            && cx.tcx().sess.target.target.options.simd_types_indirect =>
+                    {
+                        arg.make_indirect();
+                        return;
+                    }
+
+                    _ => return,
+                }
+
+                let size = arg.layout.size;
+                if arg.layout.is_unsized() || size > Pointer.size(cx) {
+                    arg.make_indirect();
+                } else {
+                    // We want to pass small aggregates as immediates, but using
+                    // a LLVM aggregate type for this leads to bad optimizations,
+                    // so we pick an appropriately sized integer type instead.
+                    arg.cast_to(Reg {
+                        kind: RegKind::Integer,
+                        size,
+                    });
+                }
+            };
+            fixup(&mut self.ret);
+            for arg in &mut self.args {
+                fixup(arg);
+            }
+            if let PassMode::Indirect(ref mut attrs, _) = self.ret.mode {
+                attrs.set(ArgAttribute::StructRet);
+            }
+            return;
+        }
+
+        if let Err(msg) = self.adjust_for_cabi(cx, abi) {
+            cx.tcx().sess.fatal(&msg);
+        }
+    }
+}
index 7b749957c3ff5e8f4ad728bcda0addc6f3a5cc85..2f71861d4dc0df57d8de5e9e87da1036af49eec2 100644 (file)
@@ -47,7 +47,7 @@
 use syntax::ast::{self, Name, Ident, NodeId};
 use syntax::attr;
 use syntax::ext::hygiene::Mark;
-use syntax::symbol::{keywords, Symbol, LocalInternedString, InternedString};
+use syntax::symbol::{keywords, sym, Symbol, LocalInternedString, InternedString};
 use syntax_pos::Span;
 
 use smallvec;
@@ -1875,11 +1875,11 @@ pub fn new(
         );
 
         let mut flags = VariantFlags::NO_VARIANT_FLAGS;
-        if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, "non_exhaustive") {
+        if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive) {
             debug!("found non-exhaustive field list for {:?}", parent_did);
             flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
         } else if let Some(variant_did) = variant_did {
-            if tcx.has_attr(variant_did, "non_exhaustive") {
+            if tcx.has_attr(variant_did, sym::non_exhaustive) {
                 debug!("found non-exhaustive field list for {:?}", variant_did);
                 flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
             }
@@ -2156,7 +2156,7 @@ fn new(
         debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr);
         let mut flags = AdtFlags::NO_ADT_FLAGS;
 
-        if kind == AdtKind::Enum && tcx.has_attr(did, "non_exhaustive") {
+        if kind == AdtKind::Enum && tcx.has_attr(did, sym::non_exhaustive) {
             debug!("found non-exhaustive variant list for {:?}", did);
             flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE;
         }
@@ -2172,7 +2172,7 @@ fn new(
         }
 
         let attrs = tcx.get_attrs(did);
-        if attr::contains_name(&attrs, "fundamental") {
+        if attr::contains_name(&attrs, sym::fundamental) {
             flags |= AdtFlags::IS_FUNDAMENTAL;
         }
         if Some(did) == tcx.lang_items().phantom_data() {
@@ -3030,7 +3030,7 @@ pub fn get_attrs(self, did: DefId) -> Attributes<'gcx> {
     }
 
     /// Determines whether an item is annotated with an attribute.
-    pub fn has_attr(self, did: DefId, attr: &str) -> bool {
+    pub fn has_attr(self, did: DefId, attr: Symbol) -> bool {
         attr::contains_name(&self.get_attrs(did), attr)
     }
 
index 4c8ed71a57ca6181298d618847d6fa36e7c27ed2..926c0f8b949193cc9376b75259d7bf936df00bca 100644 (file)
@@ -22,6 +22,7 @@
 use std::{cmp, fmt};
 use syntax::ast;
 use syntax::attr::{self, SignedInt, UnsignedInt};
+use syntax::symbol::sym;
 use syntax_pos::{Span, DUMMY_SP};
 
 #[derive(Copy, Clone, Debug)]
@@ -447,7 +448,7 @@ pub fn destructor_constraints(self, def: &'tcx ty::AdtDef)
         // Such access can be in plain sight (e.g., dereferencing
         // `*foo.0` of `Foo<'a>(&'a u32)`) or indirectly hidden
         // (e.g., calling `foo.0.clone()` of `Foo<T:Clone>`).
-        if self.has_attr(dtor, "unsafe_destructor_blind_to_params") {
+        if self.has_attr(dtor, sym::unsafe_destructor_blind_to_params) {
             debug!("destructor_constraint({:?}) - blind", def.did);
             return vec![];
         }
index 758a0d63886b1e91eadeee8cc6fa42d77aa95fe0..0200e6c53b69cc1742bdbfae1379654e8ff1a218 100644 (file)
@@ -19,7 +19,7 @@
     mut_visit::{self, MutVisitor},
     parse::ParseSess,
     ptr::P,
-    symbol::Symbol
+    symbol::{Symbol, sym}
 };
 use syntax_pos::Span;
 
@@ -58,7 +58,7 @@ impl MutVisitor for ExpandAllocatorDirectives<'_> {
     fn flat_map_item(&mut self, item: P<Item>) -> SmallVec<[P<Item>; 1]> {
         debug!("in submodule {}", self.in_submod);
 
-        let name = if attr::contains_name(&item.attrs, "global_allocator") {
+        let name = if attr::contains_name(&item.attrs, sym::global_allocator) {
             "global_allocator"
         } else {
             return mut_visit::noop_flat_map_item(item, self);
index 70d184240fccd1a6bd85d94813809eaa7ab14860..38d4b7e3f9d85504db9548447f19f8e294fec49f 100644 (file)
@@ -11,9 +11,9 @@
 
 use rustc_codegen_ssa::traits::*;
 
-use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TyLayout, Abi as LayoutAbi};
-use rustc::ty::{self, Ty, Instance};
-use rustc::ty::layout::{self, PointerKind};
+use rustc_target::abi::{HasDataLayout, LayoutOf};
+use rustc::ty::{Ty};
+use rustc::ty::layout::{self};
 
 use libc::c_uint;
 
@@ -294,23 +294,7 @@ fn memory_ty(&self, ty: &ArgType<'tcx, Ty<'tcx>>) -> &'ll Type {
     }
 }
 
-pub trait FnTypeExt<'tcx> {
-    fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self;
-    fn new(cx: &CodegenCx<'ll, 'tcx>,
-           sig: ty::FnSig<'tcx>,
-           extra_args: &[Ty<'tcx>]) -> Self;
-    fn new_vtable(cx: &CodegenCx<'ll, 'tcx>,
-                  sig: ty::FnSig<'tcx>,
-                  extra_args: &[Ty<'tcx>]) -> Self;
-    fn new_internal(
-        cx: &CodegenCx<'ll, 'tcx>,
-        sig: ty::FnSig<'tcx>,
-        extra_args: &[Ty<'tcx>],
-        mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgType<'tcx, Ty<'tcx>>,
-    ) -> Self;
-    fn adjust_for_abi(&mut self,
-                      cx: &CodegenCx<'ll, 'tcx>,
-                      abi: Abi);
+pub trait FnTypeLlvmExt<'tcx> {
     fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
     fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
     fn llvm_cconv(&self) -> llvm::CallConv;
@@ -318,356 +302,7 @@ fn adjust_for_abi(&mut self,
     fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value);
 }
 
-impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
-    fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self {
-        let sig = instance.fn_sig(cx.tcx);
-        let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
-        FnType::new(cx, sig, &[])
-    }
-
-    fn new(cx: &CodegenCx<'ll, 'tcx>,
-           sig: ty::FnSig<'tcx>,
-           extra_args: &[Ty<'tcx>]) -> Self {
-        FnType::new_internal(cx, sig, extra_args, |ty, _| {
-            ArgType::new(cx.layout_of(ty))
-        })
-    }
-
-    fn new_vtable(cx: &CodegenCx<'ll, 'tcx>,
-                  sig: ty::FnSig<'tcx>,
-                  extra_args: &[Ty<'tcx>]) -> Self {
-        FnType::new_internal(cx, sig, extra_args, |ty, arg_idx| {
-            let mut layout = cx.layout_of(ty);
-            // Don't pass the vtable, it's not an argument of the virtual fn.
-            // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
-            // or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen
-            if arg_idx == Some(0) {
-                let fat_pointer_ty = if layout.is_unsized() {
-                    // unsized `self` is passed as a pointer to `self`
-                    // FIXME (mikeyhew) change this to use &own if it is ever added to the language
-                    cx.tcx.mk_mut_ptr(layout.ty)
-                } else {
-                    match layout.abi {
-                        LayoutAbi::ScalarPair(..) => (),
-                        _ => bug!("receiver type has unsupported layout: {:?}", layout)
-                    }
-
-                    // In the case of Rc<Self>, we need to explicitly pass a *mut RcBox<Self>
-                    // with a Scalar (not ScalarPair) ABI. This is a hack that is understood
-                    // elsewhere in the compiler as a method on a `dyn Trait`.
-                    // To get the type `*mut RcBox<Self>`, we just keep unwrapping newtypes until we
-                    // get a built-in pointer type
-                    let mut fat_pointer_layout = layout;
-                    'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr()
-                        && !fat_pointer_layout.ty.is_region_ptr()
-                    {
-                        'iter_fields: for i in 0..fat_pointer_layout.fields.count() {
-                            let field_layout = fat_pointer_layout.field(cx, i);
-
-                            if !field_layout.is_zst() {
-                                fat_pointer_layout = field_layout;
-                                continue 'descend_newtypes
-                            }
-                        }
-
-                        bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout);
-                    }
-
-                    fat_pointer_layout.ty
-                };
-
-                // we now have a type like `*mut RcBox<dyn Trait>`
-                // change its layout to that of `*mut ()`, a thin pointer, but keep the same type
-                // this is understood as a special case elsewhere in the compiler
-                let unit_pointer_ty = cx.tcx.mk_mut_ptr(cx.tcx.mk_unit());
-                layout = cx.layout_of(unit_pointer_ty);
-                layout.ty = fat_pointer_ty;
-            }
-            ArgType::new(layout)
-        })
-    }
-
-    fn new_internal(
-        cx: &CodegenCx<'ll, 'tcx>,
-        sig: ty::FnSig<'tcx>,
-        extra_args: &[Ty<'tcx>],
-        mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgType<'tcx, Ty<'tcx>>,
-    ) -> Self {
-        debug!("FnType::new_internal({:?}, {:?})", sig, extra_args);
-
-        use self::Abi::*;
-        let conv = match cx.sess().target.target.adjust_abi(sig.abi) {
-            RustIntrinsic | PlatformIntrinsic |
-            Rust | RustCall => Conv::C,
-
-            // It's the ABI's job to select this, not ours.
-            System => bug!("system abi should be selected elsewhere"),
-
-            Stdcall => Conv::X86Stdcall,
-            Fastcall => Conv::X86Fastcall,
-            Vectorcall => Conv::X86VectorCall,
-            Thiscall => Conv::X86ThisCall,
-            C => Conv::C,
-            Unadjusted => Conv::C,
-            Win64 => Conv::X86_64Win64,
-            SysV64 => Conv::X86_64SysV,
-            Aapcs => Conv::ArmAapcs,
-            PtxKernel => Conv::PtxKernel,
-            Msp430Interrupt => Conv::Msp430Intr,
-            X86Interrupt => Conv::X86Intr,
-            AmdGpuKernel => Conv::AmdGpuKernel,
-
-            // These API constants ought to be more specific...
-            Cdecl => Conv::C,
-        };
-
-        let mut inputs = sig.inputs();
-        let extra_args = if sig.abi == RustCall {
-            assert!(!sig.c_variadic && extra_args.is_empty());
-
-            match sig.inputs().last().unwrap().sty {
-                ty::Tuple(tupled_arguments) => {
-                    inputs = &sig.inputs()[0..sig.inputs().len() - 1];
-                    tupled_arguments.iter().map(|k| k.expect_ty()).collect()
-                }
-                _ => {
-                    bug!("argument to function with \"rust-call\" ABI \
-                          is not a tuple");
-                }
-            }
-        } else {
-            assert!(sig.c_variadic || extra_args.is_empty());
-            extra_args.to_vec()
-        };
-
-        let target = &cx.sess().target.target;
-        let win_x64_gnu = target.target_os == "windows"
-                       && target.arch == "x86_64"
-                       && target.target_env == "gnu";
-        let linux_s390x = target.target_os == "linux"
-                       && target.arch == "s390x"
-                       && target.target_env == "gnu";
-        let linux_sparc64 = target.target_os == "linux"
-                       && target.arch == "sparc64"
-                       && target.target_env == "gnu";
-        let rust_abi = match sig.abi {
-            RustIntrinsic | PlatformIntrinsic | Rust | RustCall => true,
-            _ => false
-        };
-
-        // Handle safe Rust thin and fat pointers.
-        let adjust_for_rust_scalar = |attrs: &mut ArgAttributes,
-                                      scalar: &layout::Scalar,
-                                      layout: TyLayout<'tcx, Ty<'tcx>>,
-                                      offset: Size,
-                                      is_return: bool| {
-            // Booleans are always an i1 that needs to be zero-extended.
-            if scalar.is_bool() {
-                attrs.set(ArgAttribute::ZExt);
-                return;
-            }
-
-            // Only pointer types handled below.
-            if scalar.value != layout::Pointer {
-                return;
-            }
-
-            if scalar.valid_range.start() < scalar.valid_range.end() {
-                if *scalar.valid_range.start() > 0 {
-                    attrs.set(ArgAttribute::NonNull);
-                }
-            }
-
-            if let Some(pointee) = layout.pointee_info_at(cx, offset) {
-                if let Some(kind) = pointee.safe {
-                    attrs.pointee_size = pointee.size;
-                    attrs.pointee_align = Some(pointee.align);
-
-                    // `Box` pointer parameters never alias because ownership is transferred
-                    // `&mut` pointer parameters never alias other parameters,
-                    // or mutable global data
-                    //
-                    // `&T` where `T` contains no `UnsafeCell<U>` is immutable,
-                    // and can be marked as both `readonly` and `noalias`, as
-                    // LLVM's definition of `noalias` is based solely on memory
-                    // dependencies rather than pointer equality
-                    let no_alias = match kind {
-                        PointerKind::Shared => false,
-                        PointerKind::UniqueOwned => true,
-                        PointerKind::Frozen |
-                        PointerKind::UniqueBorrowed => !is_return
-                    };
-                    if no_alias {
-                        attrs.set(ArgAttribute::NoAlias);
-                    }
-
-                    if kind == PointerKind::Frozen && !is_return {
-                        attrs.set(ArgAttribute::ReadOnly);
-                    }
-                }
-            }
-        };
-
-        // Store the index of the last argument. This is useful for working with
-        // C-compatible variadic arguments.
-        let last_arg_idx = if sig.inputs().is_empty() {
-            None
-        } else {
-            Some(sig.inputs().len() - 1)
-        };
-
-        let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| {
-            let is_return = arg_idx.is_none();
-            let mut arg = mk_arg_type(ty, arg_idx);
-            if arg.layout.is_zst() {
-                // For some forsaken reason, x86_64-pc-windows-gnu
-                // doesn't ignore zero-sized struct arguments.
-                // The same is true for s390x-unknown-linux-gnu
-                // and sparc64-unknown-linux-gnu.
-                if is_return || rust_abi || (!win_x64_gnu && !linux_s390x && !linux_sparc64) {
-                    arg.mode = PassMode::Ignore(IgnoreMode::Zst);
-                }
-            }
-
-            // If this is a C-variadic function, this is not the return value,
-            // and there is one or more fixed arguments; ensure that the `VaList`
-            // is ignored as an argument.
-            if sig.c_variadic {
-                match (last_arg_idx, arg_idx) {
-                    (Some(last_idx), Some(cur_idx)) if last_idx == cur_idx => {
-                        let va_list_did = match cx.tcx.lang_items().va_list() {
-                            Some(did) => did,
-                            None => bug!("`va_list` lang item required for C-variadic functions"),
-                        };
-                        match ty.sty {
-                            ty::Adt(def, _) if def.did == va_list_did => {
-                                // This is the "spoofed" `VaList`. Set the arguments mode
-                                // so that it will be ignored.
-                                arg.mode = PassMode::Ignore(IgnoreMode::CVarArgs);
-                            },
-                            _ => (),
-                        }
-                    }
-                    _ => {}
-                }
-            }
-
-            // FIXME(eddyb) other ABIs don't have logic for scalar pairs.
-            if !is_return && rust_abi {
-                if let layout::Abi::ScalarPair(ref a, ref b) = arg.layout.abi {
-                    let mut a_attrs = ArgAttributes::new();
-                    let mut b_attrs = ArgAttributes::new();
-                    adjust_for_rust_scalar(&mut a_attrs,
-                                           a,
-                                           arg.layout,
-                                           Size::ZERO,
-                                           false);
-                    adjust_for_rust_scalar(&mut b_attrs,
-                                           b,
-                                           arg.layout,
-                                           a.value.size(cx).align_to(b.value.align(cx).abi),
-                                           false);
-                    arg.mode = PassMode::Pair(a_attrs, b_attrs);
-                    return arg;
-                }
-            }
-
-            if let layout::Abi::Scalar(ref scalar) = arg.layout.abi {
-                if let PassMode::Direct(ref mut attrs) = arg.mode {
-                    adjust_for_rust_scalar(attrs,
-                                           scalar,
-                                           arg.layout,
-                                           Size::ZERO,
-                                           is_return);
-                }
-            }
-
-            arg
-        };
-
-        let mut fn_ty = FnType {
-            ret: arg_of(sig.output(), None),
-            args: inputs.iter().cloned().chain(extra_args).enumerate().map(|(i, ty)| {
-                arg_of(ty, Some(i))
-            }).collect(),
-            c_variadic: sig.c_variadic,
-            conv,
-        };
-        fn_ty.adjust_for_abi(cx, sig.abi);
-        fn_ty
-    }
-
-    fn adjust_for_abi(&mut self,
-                      cx: &CodegenCx<'ll, 'tcx>,
-                      abi: Abi) {
-        if abi == Abi::Unadjusted { return }
-
-        if abi == Abi::Rust || abi == Abi::RustCall ||
-           abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
-            let fixup = |arg: &mut ArgType<'tcx, Ty<'tcx>>| {
-                if arg.is_ignore() { return; }
-
-                match arg.layout.abi {
-                    layout::Abi::Aggregate { .. } => {}
-
-                    // This is a fun case! The gist of what this is doing is
-                    // that we want callers and callees to always agree on the
-                    // ABI of how they pass SIMD arguments. If we were to *not*
-                    // make these arguments indirect then they'd be immediates
-                    // in LLVM, which means that they'd used whatever the
-                    // appropriate ABI is for the callee and the caller. That
-                    // means, for example, if the caller doesn't have AVX
-                    // enabled but the callee does, then passing an AVX argument
-                    // across this boundary would cause corrupt data to show up.
-                    //
-                    // This problem is fixed by unconditionally passing SIMD
-                    // arguments through memory between callers and callees
-                    // which should get them all to agree on ABI regardless of
-                    // target feature sets. Some more information about this
-                    // issue can be found in #44367.
-                    //
-                    // Note that the platform intrinsic ABI is exempt here as
-                    // that's how we connect up to LLVM and it's unstable
-                    // anyway, we control all calls to it in libstd.
-                    layout::Abi::Vector { .. }
-                        if abi != Abi::PlatformIntrinsic &&
-                            cx.sess().target.target.options.simd_types_indirect =>
-                    {
-                        arg.make_indirect();
-                        return
-                    }
-
-                    _ => return
-                }
-
-                let size = arg.layout.size;
-                if arg.layout.is_unsized() || size > layout::Pointer.size(cx) {
-                    arg.make_indirect();
-                } else {
-                    // We want to pass small aggregates as immediates, but using
-                    // a LLVM aggregate type for this leads to bad optimizations,
-                    // so we pick an appropriately sized integer type instead.
-                    arg.cast_to(Reg {
-                        kind: RegKind::Integer,
-                        size
-                    });
-                }
-            };
-            fixup(&mut self.ret);
-            for arg in &mut self.args {
-                fixup(arg);
-            }
-            if let PassMode::Indirect(ref mut attrs, _) = self.ret.mode {
-                attrs.set(ArgAttribute::StructRet);
-            }
-            return;
-        }
-
-        if let Err(msg) = self.adjust_for_cabi(cx, abi) {
-            cx.sess().fatal(&msg);
-        }
-    }
-
+impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
     fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
         let args_capacity: usize = self.args.iter().map(|arg|
             if arg.pad.is_some() { 1 } else { 0 } +
@@ -836,22 +471,6 @@ fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll V
     }
 }
 
-impl AbiMethods<'tcx> for CodegenCx<'ll, 'tcx> {
-    fn new_fn_type(&self, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> FnType<'tcx, Ty<'tcx>> {
-        FnType::new(&self, sig, extra_args)
-    }
-    fn new_vtable(
-        &self,
-        sig: ty::FnSig<'tcx>,
-        extra_args: &[Ty<'tcx>]
-    ) -> FnType<'tcx, Ty<'tcx>> {
-        FnType::new_vtable(&self, sig, extra_args)
-    }
-    fn fn_type_of_instance(&self, instance: &Instance<'tcx>) -> FnType<'tcx, Ty<'tcx>> {
-        FnType::of_instance(&self, instance)
-    }
-}
-
 impl AbiBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
     fn apply_attrs_callsite(
         &mut self,
index b15a64c966b1b34376ea4c98ca06f92605922b43..f26684d9ef04ae4a46c4ee87f1884a1f33af350b 100644 (file)
@@ -321,12 +321,12 @@ pub fn provide(providers: &mut Providers<'_>) {
             // rustdoc needs to be able to document functions that use all the features, so
             // whitelist them all
             Lrc::new(llvm_util::all_known_features()
-                .map(|(a, b)| (a.to_string(), b.map(|s| s.to_string())))
+                .map(|(a, b)| (a.to_string(), b))
                 .collect())
         } else {
             Lrc::new(llvm_util::target_feature_whitelist(tcx.sess)
                 .iter()
-                .map(|&(a, b)| (a.to_string(), b.map(|s| s.to_string())))
+                .map(|&(a, b)| (a.to_string(), b))
                 .collect())
         }
     };
index bc2bb97a19e5471f5a8e6e5739eca5d200f8fe8f..48808eea3045ea892382cf08046db9297eb4c466 100644 (file)
@@ -18,6 +18,7 @@
 use rustc_codegen_ssa::base::to_immediate;
 use rustc_codegen_ssa::mir::operand::{OperandValue, OperandRef};
 use rustc_codegen_ssa::mir::place::PlaceRef;
+use rustc_target::spec::{HasTargetSpec, Target};
 use std::borrow::Cow;
 use std::ops::{Deref, Range};
 use std::ptr;
@@ -72,6 +73,12 @@ fn param_env(&self) -> ty::ParamEnv<'tcx> {
     }
 }
 
+impl HasTargetSpec for Builder<'_, '_, 'tcx> {
+    fn target_spec(&self) -> &Target {
+        &self.cx.target_spec()
+    }
+}
+
 impl ty::layout::LayoutOf for Builder<'_, '_, 'tcx> {
     type Ty = Ty<'tcx>;
     type TyLayout = TyLayout<'tcx>;
index 8c83e9ef538e5dfc40481dac5cd7ae5f76f55d82..5f47108309fbfdac3749da165bba96e0682c90c5 100644 (file)
@@ -14,6 +14,7 @@
 use rustc::hir::Node;
 use syntax_pos::Span;
 use rustc_target::abi::HasDataLayout;
+use syntax::symbol::sym;
 use syntax_pos::symbol::LocalInternedString;
 use rustc::ty::{self, Ty};
 use rustc_codegen_ssa::traits::*;
@@ -248,7 +249,7 @@ impl CodegenCx<'ll, 'tcx> {
             debug!("get_static: sym={} attrs={:?}", sym, attrs);
 
             for attr in attrs {
-                if attr.check_name("thread_local") {
+                if attr.check_name(sym::thread_local) {
                     llvm::set_thread_local_mode(g, self.tls_model);
                 }
             }
index 91496ffbe557a4b65aea8c791f76c6d1bf4958cc..04c9e93c7a527cf79c41c18d035706cc740ca987 100644 (file)
@@ -9,6 +9,7 @@
 use rustc_codegen_ssa::traits::*;
 
 use syntax::attr;
+use syntax::symbol::sym;
 
 
 /// Inserts a side-effect free instruction sequence that makes sure that the
@@ -66,8 +67,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx<'ll, '_>)
 
 pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
     let omit_gdb_pretty_printer_section =
-        attr::contains_name(&cx.tcx.hir().krate_attrs(),
-                            "omit_gdb_pretty_printer_section");
+        attr::contains_name(&cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section);
 
     !omit_gdb_pretty_printer_section &&
     cx.sess().opts.debuginfo != DebugInfo::None &&
index 3febcb019ce29ff32677661acd312c0220e93037..bcb14b8899ec245bb728af3535bc91e0557bf1f8 100644 (file)
 
 use crate::llvm;
 use crate::llvm::AttributePlace::Function;
-use crate::abi::{FnType, FnTypeExt};
+use crate::abi::{FnType, FnTypeLlvmExt};
 use crate::attributes;
 use crate::context::CodegenCx;
 use crate::type_::Type;
 use crate::value::Value;
 use rustc::ty::{self, PolyFnSig};
-use rustc::ty::layout::LayoutOf;
+use rustc::ty::layout::{FnTypeExt, LayoutOf};
 use rustc::session::config::Sanitizer;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_codegen_ssa::traits::*;
index f1b8d532eeb7619354756489b5afec74a4fa56ba..274c89659628d207125710f69cc65b72af37eb0a 100644 (file)
@@ -7,6 +7,7 @@
 use libc::c_int;
 use std::ffi::CString;
 use syntax::feature_gate::UnstableFeatures;
+use syntax::symbol::sym;
 
 use std::str;
 use std::slice;
@@ -93,106 +94,106 @@ unsafe fn configure_llvm(sess: &Session) {
 // to LLVM or the feature detection code will walk past the end of the feature
 // array, leading to crashes.
 
-const ARM_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("aclass", Some("arm_target_feature")),
-    ("mclass", Some("arm_target_feature")),
-    ("rclass", Some("arm_target_feature")),
-    ("dsp", Some("arm_target_feature")),
-    ("neon", Some("arm_target_feature")),
-    ("v5te", Some("arm_target_feature")),
-    ("v6", Some("arm_target_feature")),
-    ("v6k", Some("arm_target_feature")),
-    ("v6t2", Some("arm_target_feature")),
-    ("v7", Some("arm_target_feature")),
-    ("v8", Some("arm_target_feature")),
-    ("vfp2", Some("arm_target_feature")),
-    ("vfp3", Some("arm_target_feature")),
-    ("vfp4", Some("arm_target_feature")),
+const ARM_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("aclass", Some(sym::arm_target_feature)),
+    ("mclass", Some(sym::arm_target_feature)),
+    ("rclass", Some(sym::arm_target_feature)),
+    ("dsp", Some(sym::arm_target_feature)),
+    ("neon", Some(sym::arm_target_feature)),
+    ("v5te", Some(sym::arm_target_feature)),
+    ("v6", Some(sym::arm_target_feature)),
+    ("v6k", Some(sym::arm_target_feature)),
+    ("v6t2", Some(sym::arm_target_feature)),
+    ("v7", Some(sym::arm_target_feature)),
+    ("v8", Some(sym::arm_target_feature)),
+    ("vfp2", Some(sym::arm_target_feature)),
+    ("vfp3", Some(sym::arm_target_feature)),
+    ("vfp4", Some(sym::arm_target_feature)),
 ];
 
-const AARCH64_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("fp", Some("aarch64_target_feature")),
-    ("neon", Some("aarch64_target_feature")),
-    ("sve", Some("aarch64_target_feature")),
-    ("crc", Some("aarch64_target_feature")),
-    ("crypto", Some("aarch64_target_feature")),
-    ("ras", Some("aarch64_target_feature")),
-    ("lse", Some("aarch64_target_feature")),
-    ("rdm", Some("aarch64_target_feature")),
-    ("fp16", Some("aarch64_target_feature")),
-    ("rcpc", Some("aarch64_target_feature")),
-    ("dotprod", Some("aarch64_target_feature")),
-    ("v8.1a", Some("aarch64_target_feature")),
-    ("v8.2a", Some("aarch64_target_feature")),
-    ("v8.3a", Some("aarch64_target_feature")),
+const AARCH64_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("fp", Some(sym::aarch64_target_feature)),
+    ("neon", Some(sym::aarch64_target_feature)),
+    ("sve", Some(sym::aarch64_target_feature)),
+    ("crc", Some(sym::aarch64_target_feature)),
+    ("crypto", Some(sym::aarch64_target_feature)),
+    ("ras", Some(sym::aarch64_target_feature)),
+    ("lse", Some(sym::aarch64_target_feature)),
+    ("rdm", Some(sym::aarch64_target_feature)),
+    ("fp16", Some(sym::aarch64_target_feature)),
+    ("rcpc", Some(sym::aarch64_target_feature)),
+    ("dotprod", Some(sym::aarch64_target_feature)),
+    ("v8.1a", Some(sym::aarch64_target_feature)),
+    ("v8.2a", Some(sym::aarch64_target_feature)),
+    ("v8.3a", Some(sym::aarch64_target_feature)),
 ];
 
-const X86_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("adx", Some("adx_target_feature")),
+const X86_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("adx", Some(sym::adx_target_feature)),
     ("aes", None),
     ("avx", None),
     ("avx2", None),
-    ("avx512bw", Some("avx512_target_feature")),
-    ("avx512cd", Some("avx512_target_feature")),
-    ("avx512dq", Some("avx512_target_feature")),
-    ("avx512er", Some("avx512_target_feature")),
-    ("avx512f", Some("avx512_target_feature")),
-    ("avx512ifma", Some("avx512_target_feature")),
-    ("avx512pf", Some("avx512_target_feature")),
-    ("avx512vbmi", Some("avx512_target_feature")),
-    ("avx512vl", Some("avx512_target_feature")),
-    ("avx512vpopcntdq", Some("avx512_target_feature")),
+    ("avx512bw", Some(sym::avx512_target_feature)),
+    ("avx512cd", Some(sym::avx512_target_feature)),
+    ("avx512dq", Some(sym::avx512_target_feature)),
+    ("avx512er", Some(sym::avx512_target_feature)),
+    ("avx512f", Some(sym::avx512_target_feature)),
+    ("avx512ifma", Some(sym::avx512_target_feature)),
+    ("avx512pf", Some(sym::avx512_target_feature)),
+    ("avx512vbmi", Some(sym::avx512_target_feature)),
+    ("avx512vl", Some(sym::avx512_target_feature)),
+    ("avx512vpopcntdq", Some(sym::avx512_target_feature)),
     ("bmi1", None),
     ("bmi2", None),
-    ("cmpxchg16b", Some("cmpxchg16b_target_feature")),
-    ("f16c", Some("f16c_target_feature")),
+    ("cmpxchg16b", Some(sym::cmpxchg16b_target_feature)),
+    ("f16c", Some(sym::f16c_target_feature)),
     ("fma", None),
     ("fxsr", None),
     ("lzcnt", None),
-    ("mmx", Some("mmx_target_feature")),
-    ("movbe", Some("movbe_target_feature")),
+    ("mmx", Some(sym::mmx_target_feature)),
+    ("movbe", Some(sym::movbe_target_feature)),
     ("pclmulqdq", None),
     ("popcnt", None),
     ("rdrand", None),
     ("rdseed", None),
-    ("rtm", Some("rtm_target_feature")),
+    ("rtm", Some(sym::rtm_target_feature)),
     ("sha", None),
     ("sse", None),
     ("sse2", None),
     ("sse3", None),
     ("sse4.1", None),
     ("sse4.2", None),
-    ("sse4a", Some("sse4a_target_feature")),
+    ("sse4a", Some(sym::sse4a_target_feature)),
     ("ssse3", None),
-    ("tbm", Some("tbm_target_feature")),
+    ("tbm", Some(sym::tbm_target_feature)),
     ("xsave", None),
     ("xsavec", None),
     ("xsaveopt", None),
     ("xsaves", None),
 ];
 
-const HEXAGON_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("hvx", Some("hexagon_target_feature")),
-    ("hvx-double", Some("hexagon_target_feature")),
+const HEXAGON_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("hvx", Some(sym::hexagon_target_feature)),
+    ("hvx-double", Some(sym::hexagon_target_feature)),
 ];
 
-const POWERPC_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("altivec", Some("powerpc_target_feature")),
-    ("power8-altivec", Some("powerpc_target_feature")),
-    ("power9-altivec", Some("powerpc_target_feature")),
-    ("power8-vector", Some("powerpc_target_feature")),
-    ("power9-vector", Some("powerpc_target_feature")),
-    ("vsx", Some("powerpc_target_feature")),
+const POWERPC_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("altivec", Some(sym::powerpc_target_feature)),
+    ("power8-altivec", Some(sym::powerpc_target_feature)),
+    ("power9-altivec", Some(sym::powerpc_target_feature)),
+    ("power8-vector", Some(sym::powerpc_target_feature)),
+    ("power9-vector", Some(sym::powerpc_target_feature)),
+    ("vsx", Some(sym::powerpc_target_feature)),
 ];
 
-const MIPS_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("fp64", Some("mips_target_feature")),
-    ("msa", Some("mips_target_feature")),
+const MIPS_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("fp64", Some(sym::mips_target_feature)),
+    ("msa", Some(sym::mips_target_feature)),
 ];
 
-const WASM_WHITELIST: &[(&str, Option<&str>)] = &[
-    ("simd128", Some("wasm_target_feature")),
-    ("atomics", Some("wasm_target_feature")),
+const WASM_WHITELIST: &[(&str, Option<Symbol>)] = &[
+    ("simd128", Some(sym::wasm_target_feature)),
+    ("atomics", Some(sym::wasm_target_feature)),
 ];
 
 /// When rustdoc is running, provide a list of all known features so that all their respective
@@ -200,7 +201,7 @@ unsafe fn configure_llvm(sess: &Session) {
 ///
 /// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this
 /// iterator!
-pub fn all_known_features() -> impl Iterator<Item=(&'static str, Option<&'static str>)> {
+pub fn all_known_features() -> impl Iterator<Item=(&'static str, Option<Symbol>)> {
     ARM_WHITELIST.iter().cloned()
         .chain(AARCH64_WHITELIST.iter().cloned())
         .chain(X86_WHITELIST.iter().cloned())
@@ -247,7 +248,7 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> {
 }
 
 pub fn target_feature_whitelist(sess: &Session)
-    -> &'static [(&'static str, Option<&'static str>)]
+    -> &'static [(&'static str, Option<Symbol>)]
 {
     match &*sess.target.target.arch {
         "arm" => ARM_WHITELIST,
index a5ed64a66a39da1ebdf3fce19c258a8559516b04..a3d3f0756a5f3997405faf73485934f3bd9987de 100644 (file)
@@ -10,7 +10,7 @@
 
 use crate::common;
 use crate::type_of::LayoutLlvmExt;
-use crate::abi::{LlvmType, FnTypeExt};
+use crate::abi::{LlvmType, FnTypeLlvmExt};
 use syntax::ast;
 use rustc::ty::Ty;
 use rustc::ty::layout::{self, Align, Size, TyLayout};
index ff25ed9256613c867cae9a3b9315a5549b34b67d..800bf505125d677842d88e8023848b91edb342fa 100644 (file)
@@ -1,8 +1,8 @@
-use crate::abi::{FnType, FnTypeExt};
+use crate::abi::{FnType};
 use crate::common::*;
 use crate::type_::Type;
 use rustc::ty::{self, Ty, TypeFoldable};
-use rustc::ty::layout::{self, Align, LayoutOf, PointeeInfo, Size, TyLayout};
+use rustc::ty::layout::{self, Align, LayoutOf, FnTypeExt, PointeeInfo, Size, TyLayout};
 use rustc_target::abi::{FloatTy, TyLayoutMethods};
 use rustc_mir::monomorphize::item::DefPathBasedNames;
 use rustc_codegen_ssa::traits::*;
index 576bcc8f38e656274d2da9d6e7822cf7d0e753c6..6320d8a671ddbfd66f87de8060b86e9641839956 100644 (file)
@@ -28,7 +28,7 @@
 use syntax::attr;
 use syntax::ext::hygiene::Mark;
 use syntax_pos::MultiSpan;
-use syntax_pos::symbol::Symbol;
+use syntax_pos::symbol::{Symbol, sym};
 use jobserver::{Client, Acquired};
 
 use std::any::Any;
@@ -382,11 +382,11 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
     let sess = tcx.sess;
     let crate_name = tcx.crate_name(LOCAL_CRATE);
     let crate_hash = tcx.crate_hash(LOCAL_CRATE);
-    let no_builtins = attr::contains_name(&tcx.hir().krate().attrs, "no_builtins");
+    let no_builtins = attr::contains_name(&tcx.hir().krate().attrs, sym::no_builtins);
     let subsystem = attr::first_attr_value_str_by_name(&tcx.hir().krate().attrs,
-                                                       "windows_subsystem");
+                                                       sym::windows_subsystem);
     let windows_subsystem = subsystem.map(|subsystem| {
-        if subsystem != "windows" && subsystem != "console" {
+        if subsystem != sym::windows && subsystem != sym::console {
             tcx.sess.fatal(&format!("invalid windows subsystem `{}`, only \
                                      `windows` and `console` are allowed",
                                     subsystem));
index e64c847db651bbaebdd0da0a7e981f3e45225c05..96b8558c1d2c447f2b8149f6d71cf647f5696260 100644 (file)
@@ -1,6 +1,6 @@
 use rustc::middle::lang_items;
 use rustc::ty::{self, Ty, TypeFoldable};
-use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
+use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt};
 use rustc::mir::{self, Place, PlaceBase, Static, StaticKind};
 use rustc::mir::interpret::InterpError;
 use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode};
@@ -334,14 +334,14 @@ fn codegen_drop_terminator<'b>(
                     ty::ParamEnv::reveal_all(),
                     &sig,
                 );
-                let fn_ty = bx.new_vtable(sig, &[]);
+                let fn_ty = FnType::new_vtable(&bx, sig, &[]);
                 let vtable = args[1];
                 args = &args[..1];
                 (meth::DESTRUCTOR.get_fn(&mut bx, vtable, &fn_ty), fn_ty)
             }
             _ => {
                 (bx.get_fn(drop_fn),
-                 bx.fn_type_of_instance(&drop_fn))
+                 FnType::of_instance(&bx, &drop_fn))
             }
         };
         helper.do_call(self, &mut bx, fn_ty, drop_fn, args,
@@ -439,7 +439,7 @@ fn codegen_assert_terminator<'b>(
         // Obtain the panic entry point.
         let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item);
         let instance = ty::Instance::mono(bx.tcx(), def_id);
-        let fn_ty = bx.fn_type_of_instance(&instance);
+        let fn_ty = FnType::of_instance(&bx, &instance);
         let llfn = bx.get_fn(instance);
 
         // Codegen the actual panic invoke/call.
@@ -518,7 +518,7 @@ fn codegen_call_terminator<'b>(
 
         let fn_ty = match def {
             Some(ty::InstanceDef::Virtual(..)) => {
-                bx.new_vtable(sig, &extra_args)
+                FnType::new_vtable(&bx, sig, &extra_args)
             }
             Some(ty::InstanceDef::DropGlue(_, None)) => {
                 // Empty drop glue; a no-op.
@@ -526,7 +526,7 @@ fn codegen_call_terminator<'b>(
                 helper.funclet_br(self, &mut bx, target);
                 return;
             }
-            _ => bx.new_fn_type(sig, &extra_args)
+            _ => FnType::new(&bx, sig, &extra_args)
         };
 
         // Emit a panic or a no-op for `panic_if_uninhabited`.
@@ -556,7 +556,7 @@ fn codegen_call_terminator<'b>(
                 let def_id =
                     common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem);
                 let instance = ty::Instance::mono(bx.tcx(), def_id);
-                let fn_ty = bx.fn_type_of_instance(&instance);
+                let fn_ty = FnType::of_instance(&bx, &instance);
                 let llfn = bx.get_fn(instance);
 
                 // Codegen the actual panic invoke/call.
index fcf099235aa14f2ac4c00316de6fe018b7ca0533..060d7d18625fcd358323405f1570db82a632d9cc 100644 (file)
@@ -1,5 +1,5 @@
 use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts};
-use rustc::ty::layout::{TyLayout, HasTyCtxt};
+use rustc::ty::layout::{TyLayout, HasTyCtxt, FnTypeExt};
 use rustc::mir::{self, Mir};
 use rustc::session::config::DebugInfo;
 use rustc_mir::monomorphize::Instance;
@@ -202,7 +202,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
 ) {
     assert!(!instance.substs.needs_infer());
 
-    let fn_ty = cx.new_fn_type(sig, &[]);
+    let fn_ty = FnType::new(cx, sig, &[]);
     debug!("fn_ty: {:?}", fn_ty);
     let mut debug_context =
         cx.create_function_debug_context(instance, sig, llfn, mir);
index 8d3e64c1aa6c72afaed12d24f4a2a517b56a082f..586db5cfabea44c83c1e4bafdeffca034818b86d 100644 (file)
@@ -5,6 +5,7 @@
 use rustc::middle::lang_items::ExchangeMallocFnLangItem;
 use rustc_apfloat::{ieee, Float, Status, Round};
 use std::{u128, i128};
+use syntax::symbol::sym;
 
 use crate::base;
 use crate::MemFlags;
@@ -181,9 +182,8 @@ pub fn codegen_rvalue_operand(
                     mir::CastKind::Pointer(PointerCast::ReifyFnPointer) => {
                         match operand.layout.ty.sty {
                             ty::FnDef(def_id, substs) => {
-                                if bx.cx().tcx().has_attr(def_id, "rustc_args_required_const") {
-                                    bug!("reifying a fn ptr that requires \
-                                          const arguments");
+                                if bx.cx().tcx().has_attr(def_id, sym::rustc_args_required_const) {
+                                    bug!("reifying a fn ptr that requires const arguments");
                                 }
                                 OperandValue::Immediate(
                                     callee::resolve_and_get_fn(bx.cx(), def_id, substs))
index a8fd4e1d2c7c756853466f47edb41708ece38c67..509255c37be701853dd2f00e15406fa77c0d189e 100644 (file)
@@ -1,13 +1,7 @@
 use super::BackendTypes;
-use rustc::ty::{FnSig, Instance, Ty};
+use rustc::ty::{Ty};
 use rustc_target::abi::call::FnType;
 
-pub trait AbiMethods<'tcx> {
-    fn new_fn_type(&self, sig: FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> FnType<'tcx, Ty<'tcx>>;
-    fn new_vtable(&self, sig: FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> FnType<'tcx, Ty<'tcx>>;
-    fn fn_type_of_instance(&self, instance: &Instance<'tcx>) -> FnType<'tcx, Ty<'tcx>>;
-}
-
 pub trait AbiBuilderMethods<'tcx>: BackendTypes {
     fn apply_attrs_callsite(&mut self, ty: &FnType<'tcx, Ty<'tcx>>, callsite: Self::Value);
     fn get_param(&self, index: usize) -> Self::Value;
index a3f99cd869e28f5851aebc854d63d57dc9c175da..0c4c4547a7955a1f0ad3ffdd391ea11d678509b4 100644 (file)
@@ -11,6 +11,7 @@
 use crate::MemFlags;
 use rustc::ty::Ty;
 use rustc::ty::layout::{Align, Size, HasParamEnv};
+use rustc_target::spec::{HasTargetSpec};
 use std::ops::Range;
 use std::iter::TrustedLen;
 
@@ -30,6 +31,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>:
     + AsmBuilderMethods<'tcx>
     + StaticBuilderMethods<'tcx>
     + HasParamEnv<'tcx>
+    + HasTargetSpec
 
 {
     fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self;
index c237cd8bd2645b009b33536175a1dada09b4dd90..2bb619e79f5e06ee0b0781c46463e0433d94ca41 100644 (file)
@@ -27,7 +27,7 @@
 mod type_;
 mod write;
 
-pub use self::abi::{AbiBuilderMethods, AbiMethods};
+pub use self::abi::{AbiBuilderMethods};
 pub use self::asm::{AsmBuilderMethods, AsmMethods};
 pub use self::backend::{Backend, BackendTypes, ExtraBackendMethods};
 pub use self::builder::{BuilderMethods, OverflowOp};
@@ -41,7 +41,8 @@
     ArgTypeMethods, BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods, TypeMethods,
 };
 pub use self::write::{ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods};
-use rustc::ty::layout::{HasParamEnv};
+use rustc::ty::layout::{HasParamEnv, HasTyCtxt};
+use rustc_target::spec::{HasTargetSpec};
 
 
 use std::fmt;
@@ -56,11 +57,12 @@ pub trait CodegenMethods<'tcx>:
     + ConstMethods<'tcx>
     + StaticMethods
     + DebugInfoMethods<'tcx>
-    + AbiMethods<'tcx>
     + DeclareMethods<'tcx>
     + AsmMethods<'tcx>
     + PreDefineMethods<'tcx>
     + HasParamEnv<'tcx>
+    + HasTyCtxt<'tcx>
+    + HasTargetSpec
 {
 }
 
@@ -71,11 +73,12 @@ impl<'tcx, T> CodegenMethods<'tcx> for T where
         + ConstMethods<'tcx>
         + StaticMethods
         + DebugInfoMethods<'tcx>
-        + AbiMethods<'tcx>
         + DeclareMethods<'tcx>
         + AsmMethods<'tcx>
         + PreDefineMethods<'tcx>
         + HasParamEnv<'tcx>
+        + HasTyCtxt<'tcx>
+        + HasTargetSpec
 {
 }
 
index 437515f1e9ab4855744cd09cb19ebbcc31321fc5..b4ba90c61f65054fb2242d9825eba54466f96227 100644 (file)
@@ -23,6 +23,7 @@
 
 use rustc::ty::TyCtxt;
 use rustc::hir::def_id::LOCAL_CRATE;
+use syntax::symbol::sym;
 
 pub mod link;
 pub mod codegen_backend;
@@ -35,7 +36,7 @@
 /// reporting an error.
 pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_, '_, '_>) {
     if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) {
-        if tcx.has_attr(def_id, "rustc_error") {
+        if tcx.has_attr(def_id, sym::rustc_error) {
             tcx.sess.span_fatal(tcx.def_span(def_id), "compilation successful");
         }
     }
index f3a1b219f8a84d1929119f01019d0d253b4f46be..a2ac64fa7e0c659501ed309b202d20e9326b0561 100644 (file)
@@ -2,6 +2,7 @@
 use rustc::session::Session;
 use std::path::{Path, PathBuf};
 use syntax::{ast, attr};
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 pub fn out_filename(sess: &Session,
@@ -49,13 +50,13 @@ pub fn find_crate_name(sess: Option<&Session>,
     // as used. After doing this, however, we still prioritize a crate name from
     // the command line over one found in the #[crate_name] attribute. If we
     // find both we ensure that they're the same later on as well.
-    let attr_crate_name = attr::find_by_name(attrs, "crate_name")
+    let attr_crate_name = attr::find_by_name(attrs, sym::crate_name)
         .and_then(|at| at.value_str().map(|s| (at, s)));
 
     if let Some(sess) = sess {
         if let Some(ref s) = sess.opts.crate_name {
             if let Some((attr, name)) = attr_crate_name {
-                if name != &**s {
+                if name.as_str() != *s {
                     let msg = format!("--crate-name and #[crate_name] are \
                                        required to match, but `{}` != `{}`",
                                       s, name);
index 6a2b6f1321b88a9420fed6add0f5e1965b7686d1..27ae0b97e59452f406c34d87ecfb133f74d7e8c4 100644 (file)
@@ -6,11 +6,11 @@
 
 use rustc::hir;
 use rustc::ty::TyCtxt;
-
 use rustc_mir::monomorphize::Instance;
+use syntax::symbol::{Symbol, sym};
 
-const SYMBOL_NAME: &'static str = "rustc_symbol_name";
-const DEF_PATH: &'static str = "rustc_def_path";
+const SYMBOL_NAME: Symbol = sym::rustc_symbol_name;
+const DEF_PATH: Symbol = sym::rustc_def_path;
 
 pub fn report_symbol_names<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     // if the `rustc_attrs` feature is not enabled, then the
index 255c5fd7fe7ec8938e266e60c9c51b503d587c51..b63701dbc0967d1209718f55b6511c86b8134961 100644 (file)
@@ -44,7 +44,6 @@ pub struct flock {
         }
 
         #[cfg(any(target_os = "dragonfly",
-                  target_os = "bitrig",
                   target_os = "netbsd",
                   target_os = "openbsd"))]
         mod os {
index 5b42b049b5b189862f57adf3e262e2597487e2d3..02f8eee67b15118ffed36a9b0b19f79054a286f7 100644 (file)
@@ -63,6 +63,7 @@
 use syntax::source_map::FileLoader;
 use syntax::feature_gate::{GatedCfg, UnstableFeatures};
 use syntax::parse::{self, PResult};
+use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, MultiSpan, FileName};
 
 pub mod pretty;
@@ -669,7 +670,7 @@ fn print_crate_info(codegen_backend: &dyn CodegenBackend,
                         // through to build scripts.
                         let value = value.as_ref().map(|s| s.as_str());
                         let value = value.as_ref().map(|s| s.as_ref());
-                        if name != "target_feature" || value != Some("crt-static") {
+                        if name != sym::target_feature || value != Some("crt-static") {
                             if !allow_unstable_cfg && gated_cfg.is_some() {
                                 return None
                             }
index fc8bf0baa99f6239e51177312d4f7554a35777ea..c74ed5ec30c3cade8d6b7b91cbf1dedc92a4af44 100644 (file)
@@ -805,8 +805,7 @@ pub fn print_after_hir_lowering<'tcx>(
                                             src_name,
                                             &mut rdr,
                                             box out,
-                                            annotation.pp_ann(),
-                                            true)
+                                            annotation.pp_ann())
                 })
             }
 
@@ -829,8 +828,7 @@ pub fn print_after_hir_lowering<'tcx>(
                                                                          src_name,
                                                                          &mut rdr,
                                                                          box out,
-                                                                         annotation.pp_ann(),
-                                                                         true);
+                                                                         annotation.pp_ann());
                     for node_id in uii.all_matching_node_ids(hir_map) {
                         let node = hir_map.get(node_id);
                         pp_state.print_node(node)?;
index 2c83501c86f523f8359add23cff00bed8209c457..04dad9c5355c5b6028416a6a8cac8633660d8335 100644 (file)
 use rustc::ty::TyCtxt;
 use std::collections::BTreeSet;
 use syntax::ast;
+use syntax::symbol::{Symbol, sym};
 use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED,
                  ATTR_EXPECTED_CGU_REUSE};
 
-const MODULE: &str = "module";
-const CFG: &str = "cfg";
-const KIND: &str = "kind";
+const MODULE: Symbol = sym::module;
+const CFG: Symbol = sym::cfg;
+const KIND: Symbol = sym::kind;
 
 pub fn assert_module_sources<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     tcx.dep_graph.with_ignore(|| {
@@ -146,7 +147,7 @@ fn check_attr(&self, attr: &ast::Attribute) {
                                                         comp_kind);
     }
 
-    fn field(&self, attr: &ast::Attribute, name: &str) -> ast::Name {
+    fn field(&self, attr: &ast::Attribute, name: Symbol) -> ast::Name {
         for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
             if item.check_name(name) {
                 if let Some(value) = item.value_str() {
index 6f5b411946c2d8d3408beb1200a29979178c659a..f404a4f82e672a1e76958d45b3b72bb31ddac777 100644 (file)
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir::intravisit;
 use rustc::ich::{ATTR_DIRTY, ATTR_CLEAN};
-use syntax::ast::{self, Attribute, NestedMetaItem};
+use rustc::ty::TyCtxt;
 use rustc_data_structures::fx::FxHashSet;
+use syntax::ast::{self, Attribute, NestedMetaItem};
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::Span;
-use rustc::ty::TyCtxt;
 
-const EXCEPT: &str = "except";
-const LABEL: &str = "label";
-const CFG: &str = "cfg";
+const EXCEPT: Symbol = sym::except;
+const LABEL: Symbol = sym::label;
+const CFG: Symbol = sym::cfg;
 
 // Base and Extra labels to build up the labels
 
@@ -591,7 +592,7 @@ fn expect_associated_value(tcx: TyCtxt<'_, '_, '_>, item: &NestedMetaItem) -> as
 // nodes.
 pub struct FindAllAttrs<'a, 'tcx:'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    attr_names: Vec<&'static str>,
+    attr_names: Vec<Symbol>,
     found_attrs: Vec<&'tcx Attribute>,
 }
 
index 54b3e7342056041c98664df29de120d0fc6b1dff..c5ac8860ccd9b079db0146dc386df0c92fa398f8 100644 (file)
@@ -230,7 +230,7 @@ pub fn to_expansion_result(
 
 pub struct PluginInfo {
     syntax_exts: Vec<NamedSyntaxExtension>,
-    attributes: Vec<(String, AttributeType)>,
+    attributes: Vec<(Symbol, AttributeType)>,
 }
 
 pub fn register_plugins<'a>(
index 8ed03efd1a784ab8ca39ba712178d54d2e07e36d..e9f2f0410d440bb7889e27bcdc0eee798dfc3d52 100644 (file)
@@ -4,6 +4,7 @@
 use rustc::ty::TyCtxt;
 use rustc::ty::query::Providers;
 use syntax::attr;
+use syntax::symbol::sym;
 
 pub fn find<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> Option<DefId> {
     tcx.proc_macro_decls_static(LOCAL_CRATE)
@@ -27,7 +28,7 @@ struct Finder {
 
 impl<'v> ItemLikeVisitor<'v> for Finder {
     fn visit_item(&mut self, item: &hir::Item) {
-        if attr::contains_name(&item.attrs, "rustc_proc_macro_decls") {
+        if attr::contains_name(&item.attrs, sym::rustc_proc_macro_decls) {
             self.decls = Some(item.hir_id);
         }
     }
index 17523aedffb58ef2a0e4ec79c3fdf3f3b3543e52..d2d0d19180783bfd5b8fc557553514bbf0fb6731 100644 (file)
@@ -35,7 +35,7 @@
 use syntax::ast::BlockCheckMode;
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax::source_map::{FileLoader, RealFileLoader, SourceMap};
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::{self, ast, attr};
 #[cfg(not(parallel_compiler))]
 use std::{thread, panic};
@@ -495,24 +495,24 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
     let attr_types: Vec<config::CrateType> = attrs
         .iter()
         .filter_map(|a| {
-            if a.check_name("crate_type") {
+            if a.check_name(sym::crate_type) {
                 match a.value_str() {
-                    Some(ref n) if *n == "rlib" => Some(config::CrateType::Rlib),
-                    Some(ref n) if *n == "dylib" => Some(config::CrateType::Dylib),
-                    Some(ref n) if *n == "cdylib" => Some(config::CrateType::Cdylib),
-                    Some(ref n) if *n == "lib" => Some(config::default_lib_output()),
-                    Some(ref n) if *n == "staticlib" => Some(config::CrateType::Staticlib),
-                    Some(ref n) if *n == "proc-macro" => Some(config::CrateType::ProcMacro),
-                    Some(ref n) if *n == "bin" => Some(config::CrateType::Executable),
-                    Some(ref n) => {
+                    Some(sym::rlib) => Some(config::CrateType::Rlib),
+                    Some(sym::dylib) => Some(config::CrateType::Dylib),
+                    Some(sym::cdylib) => Some(config::CrateType::Cdylib),
+                    Some(sym::lib) => Some(config::default_lib_output()),
+                    Some(sym::staticlib) => Some(config::CrateType::Staticlib),
+                    Some(sym::proc_dash_macro) => Some(config::CrateType::ProcMacro),
+                    Some(sym::bin) => Some(config::CrateType::Executable),
+                    Some(n) => {
                         let crate_types = vec![
-                            Symbol::intern("rlib"),
-                            Symbol::intern("dylib"),
-                            Symbol::intern("cdylib"),
-                            Symbol::intern("lib"),
-                            Symbol::intern("staticlib"),
-                            Symbol::intern("proc-macro"),
-                            Symbol::intern("bin")
+                            sym::rlib,
+                            sym::dylib,
+                            sym::cdylib,
+                            sym::lib,
+                            sym::staticlib,
+                            sym::proc_dash_macro,
+                            sym::bin
                         ];
 
                         if let ast::MetaItemKind::NameValue(spanned) = a.meta().unwrap().node {
index f7a89271ec55f41659f8dbc197b8aafa25ff0d43..af4f1b88b0fb0ac8e8e6938c545f58d8b70b3f2e 100644 (file)
@@ -42,7 +42,7 @@
 use syntax::feature_gate::{AttributeGate, AttributeTemplate, AttributeType};
 use syntax::feature_gate::{Stability, deprecated_attributes};
 use syntax_pos::{BytePos, Span, SyntaxContext};
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
 use syntax::errors::{Applicability, DiagnosticBuilder};
 use syntax::print::pprust::expr_to_string;
 use syntax::visit::FnKind;
@@ -207,7 +207,7 @@ fn report_unsafe(&self, cx: &EarlyContext<'_>, span: Span, desc: &'static str) {
 
 impl EarlyLintPass for UnsafeCode {
     fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
-        if attr.check_name("allow_internal_unsafe") {
+        if attr.check_name(sym::allow_internal_unsafe) {
             self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \
                                                macros using unsafe without triggering \
                                                the `unsafe_code` lint at their call site");
@@ -285,7 +285,7 @@ pub struct MissingDoc {
 impl_lint_pass!(MissingDoc => [MISSING_DOCS]);
 
 fn has_doc(attr: &ast::Attribute) -> bool {
-    if !attr.check_name("doc") {
+    if !attr.check_name(sym::doc) {
         return false;
     }
 
@@ -295,7 +295,7 @@ fn has_doc(attr: &ast::Attribute) -> bool {
 
     if let Some(list) = attr.meta_item_list() {
         for meta in list {
-            if meta.check_name("include") || meta.check_name("hidden") {
+            if meta.check_name(sym::include) || meta.check_name(sym::hidden) {
                 return true;
             }
         }
@@ -355,10 +355,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
     fn enter_lint_attrs(&mut self, _: &LateContext<'_, '_>, attrs: &[ast::Attribute]) {
         let doc_hidden = self.doc_hidden() ||
                          attrs.iter().any(|attr| {
-            attr.check_name("doc") &&
+            attr.check_name(sym::doc) &&
             match attr.meta_item_list() {
                 None => false,
-                Some(l) => attr::list_contains_name(&l, "hidden"),
+                Some(l) => attr::list_contains_name(&l, sym::hidden),
             }
         });
         self.doc_hidden_stack.push(doc_hidden);
@@ -723,7 +723,7 @@ fn warn_if_doc(
 
             let span = sugared_span.take().unwrap_or_else(|| attr.span);
 
-            if attr.check_name("doc") {
+            if attr.check_name(sym::doc) {
                 let mut err = cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, "unused doc comment");
 
                 err.span_label(
@@ -829,7 +829,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
     fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
         match it.node {
             hir::ItemKind::Fn(.., ref generics, _) => {
-                if let Some(no_mangle_attr) = attr::find_by_name(&it.attrs, "no_mangle") {
+                if let Some(no_mangle_attr) = attr::find_by_name(&it.attrs, sym::no_mangle) {
                     for param in &generics.params {
                         match param.kind {
                             GenericParamKind::Lifetime { .. } => {}
@@ -856,7 +856,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
                 }
             }
             hir::ItemKind::Const(..) => {
-                if attr::contains_name(&it.attrs, "no_mangle") {
+                if attr::contains_name(&it.attrs, sym::no_mangle) {
                     // Const items do not refer to a particular location in memory, and therefore
                     // don't have anything to attach a symbol to
                     let msg = "const items should never be #[no_mangle]";
@@ -947,7 +947,7 @@ fn def_id_is_transmute(cx: &LateContext<'_, '_>, def_id: DefId) -> bool {
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnstableFeatures {
     fn check_attribute(&mut self, ctx: &LateContext<'_, '_>, attr: &ast::Attribute) {
-        if attr.check_name("feature") {
+        if attr.check_name(sym::feature) {
             if let Some(items) = attr.meta_item_list() {
                 for item in items {
                     ctx.span_lint(UNSTABLE_FEATURES, item.span(), "unstable feature");
@@ -1382,7 +1382,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
             return;
         }
 
-        if let Some(attr) = attr::find_by_name(&it.attrs, "rustc_test_marker") {
+        if let Some(attr) = attr::find_by_name(&it.attrs, sym::rustc_test_marker) {
             cx.struct_span_lint(
                 UNNAMEABLE_TEST_ITEMS,
                 attr.span,
index 7a003d14b2bf059a976c0eaddbd198a1cbc44a8c..551eded9858a35021fb31d24ccf9a6bdc860f442 100644 (file)
@@ -9,6 +9,7 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::errors::Applicability;
+use syntax::symbol::sym;
 use syntax_pos::{BytePos, symbol::Ident, Span};
 
 #[derive(PartialEq)]
@@ -253,7 +254,7 @@ fn check_mod(&mut self, cx: &LateContext<'_, '_>, _: &'tcx hir::Mod, _: Span, id
         let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name {
             Some(Ident::from_str(name))
         } else {
-            attr::find_by_name(&cx.tcx.hir().attrs_by_hir_id(hir::CRATE_HIR_ID), "crate_name")
+            attr::find_by_name(&cx.tcx.hir().attrs_by_hir_id(hir::CRATE_HIR_ID), sym::crate_name)
                 .and_then(|attr| attr.meta())
                 .and_then(|meta| {
                     meta.name_value_literal().and_then(|lit| {
@@ -315,7 +316,7 @@ fn check_fn(
             }
             FnKind::ItemFn(ident, _, header, _, attrs) => {
                 // Skip foreign-ABI #[no_mangle] functions (Issue #31924)
-                if header.abi != Abi::Rust && attr::contains_name(attrs, "no_mangle") {
+                if header.abi != Abi::Rust && attr::contains_name(attrs, sym::no_mangle) {
                     return;
                 }
                 self.check_snake_case(cx, "function", ident);
@@ -390,7 +391,7 @@ fn check_upper_case(cx: &LateContext<'_, '_>, sort: &str, ident: &Ident) {
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals {
     fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
         match it.node {
-            hir::ItemKind::Static(..) if !attr::contains_name(&it.attrs, "no_mangle") => {
+            hir::ItemKind::Static(..) if !attr::contains_name(&it.attrs, sym::no_mangle) => {
                 NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident);
             }
             hir::ItemKind::Const(..) => {
index f4ebfd79fe1db41f1bfee121dd045a1be2de7569..38b6e2c197939769be2d3f3238bf2f9672b7df7c 100644 (file)
@@ -62,7 +62,7 @@ pub fn new() -> TypeLimits {
 /// Returns `true` iff the lint was overridden.
 fn lint_overflowing_range_endpoint<'a, 'tcx>(
     cx: &LateContext<'a, 'tcx>,
-    lit: &ast::Lit,
+    lit: &hir::Lit,
     lit_val: u128,
     max: u128,
     expr: &'tcx hir::Expr,
@@ -132,7 +132,7 @@ fn uint_ty_range(uint_ty: ast::UintTy) -> (u128, u128) {
     }
 }
 
-fn get_bin_hex_repr(cx: &LateContext<'_, '_>, lit: &ast::Lit) -> Option<String> {
+fn get_bin_hex_repr(cx: &LateContext<'_, '_>, lit: &hir::Lit) -> Option<String> {
     let src = cx.sess().source_map().span_to_snippet(lit.span).ok()?;
     let firstch = src.chars().next()?;
 
@@ -249,7 +249,7 @@ fn lint_int_literal<'a, 'tcx>(
     cx: &LateContext<'a, 'tcx>,
     type_limits: &TypeLimits,
     e: &'tcx hir::Expr,
-    lit: &ast::Lit,
+    lit: &hir::Lit,
     t: ast::IntTy,
     v: u128,
 ) {
@@ -301,7 +301,7 @@ fn lint_int_literal<'a, 'tcx>(
 fn lint_uint_literal<'a, 'tcx>(
     cx: &LateContext<'a, 'tcx>,
     e: &'tcx hir::Expr,
-    lit: &ast::Lit,
+    lit: &hir::Lit,
     t: ast::UintTy,
 ) {
     let uint_type = if let ast::UintTy::Usize = t {
@@ -363,7 +363,7 @@ fn lint_literal<'a, 'tcx>(
     cx: &LateContext<'a, 'tcx>,
     type_limits: &TypeLimits,
     e: &'tcx hir::Expr,
-    lit: &ast::Lit,
+    lit: &hir::Lit,
 ) {
     match cx.tables.node_type(e.hir_id).sty {
         ty::Int(t) => {
index 92508ad51f104fcd4380027a7d54e353ff392461..c3dfd44ad8572f46ebc4ebc67411296924d30c59 100644 (file)
@@ -12,7 +12,7 @@
 use syntax::errors::Applicability;
 use syntax::feature_gate::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use syntax::print::pprust;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax::symbol::Symbol;
 use syntax::util::parser;
 use syntax_pos::Span;
@@ -170,7 +170,7 @@ fn check_must_use(
             descr_post_path: &str,
         ) -> bool {
             for attr in cx.tcx.get_attrs(def_id).iter() {
-                if attr.check_name("must_use") {
+                if attr.check_name(sym::must_use) {
                     let msg = format!("unused {}`{}`{} that must be used",
                         descr_pre_path, cx.tcx.def_path_str(def_id), descr_post_path);
                     let mut err = cx.struct_span_lint(UNUSED_MUST_USE, sp, &msg);
@@ -243,8 +243,8 @@ fn check_attribute(&mut self, cx: &LateContext<'_, '_>, attr: &ast::Attribute) {
         }
 
         let plugin_attributes = cx.sess().plugin_attributes.borrow_mut();
-        for &(ref name, ty) in plugin_attributes.iter() {
-            if ty == AttributeType::Whitelisted && attr.check_name(&**name) {
+        for &(name, ty) in plugin_attributes.iter() {
+            if ty == AttributeType::Whitelisted && attr.check_name(name) {
                 debug!("{:?} (plugin attr) is whitelisted with ty {:?}", name, ty);
                 break;
             }
@@ -262,7 +262,7 @@ fn check_attribute(&mut self, cx: &LateContext<'_, '_>, attr: &ast::Attribute) {
             // Has a plugin registered this attribute as one that must be used at
             // the crate level?
             let plugin_crate = plugin_attributes.iter()
-                .find(|&&(ref x, t)| name == x.as_str() && AttributeType::CrateLevel == t)
+                .find(|&&(x, t)| name == x && AttributeType::CrateLevel == t)
                 .is_some();
             if known_crate || plugin_crate {
                 let msg = match attr.style {
index 169c5e13718335fac55b758eb6889ba296bb0ef0..a4c7daf088ff2c9e14e052bcd9cd21ffad50f64a 100644 (file)
@@ -11,7 +11,7 @@
 #[allow(non_camel_case_types)]
 mod kw {
     syn::custom_keyword!(Keywords);
-    syn::custom_keyword!(Other);
+    syn::custom_keyword!(Symbols);
 }
 
 struct Keyword {
@@ -33,14 +33,24 @@ fn parse(input: ParseStream<'_>) -> Result<Self> {
     }
 }
 
-struct Symbol(Ident);
+struct Symbol {
+    name: Ident,
+    value: Option<LitStr>,
+}
 
 impl Parse for Symbol {
     fn parse(input: ParseStream<'_>) -> Result<Self> {
-        let ident: Ident = input.parse()?;
+        let name = input.parse()?;
+        let value = match input.parse::<Token![:]>() {
+            Ok(_) => Some(input.parse()?),
+            Err(_) => None,
+        };
         input.parse::<Token![,]>()?;
 
-        Ok(Symbol(ident))
+        Ok(Symbol {
+            name,
+            value,
+        })
     }
 }
 
@@ -69,7 +79,7 @@ fn parse(input: ParseStream<'_>) -> Result<Self> {
         braced!(content in input);
         let keywords = content.parse()?;
 
-        input.parse::<kw::Other>()?;
+        input.parse::<kw::Symbols>()?;
         let content;
         braced!(content in input);
         let symbols = content.parse()?;
@@ -116,19 +126,22 @@ pub fn symbols(input: TokenStream) -> TokenStream {
     }
 
     for symbol in &input.symbols.0 {
-        let value = &symbol.0;
-        let value_str = value.to_string();
-        check_dup(&value_str);
+        let name = &symbol.name;
+        let value = match &symbol.value {
+            Some(value) => value.value(),
+            None => name.to_string(),
+        };
+        check_dup(&value);
         prefill_stream.extend(quote! {
-            #value_str,
+            #value,
         });
         symbols_stream.extend(quote! {
-            pub const #value: Symbol = Symbol::new(#counter);
+            pub const #name: Symbol = Symbol::new(#counter);
         });
         counter += 1;
     }
 
-    TokenStream::from(quote! {
+    let tt = TokenStream::from(quote! {
         macro_rules! keywords {
             () => {
                 #keyword_stream
@@ -159,5 +172,11 @@ pub fn fresh() -> Self {
                 ])
             }
         }
-    })
+    });
+
+    // To see the generated code generated, uncomment this line, recompile, and
+    // run the resulting output through `rustfmt`.
+    //eprintln!("{}", tt);
+
+    tt
 }
index c47d7d85a3769cd7cfb61ff20c9c55b51fa086d2..7f2a1c0b4b1d11d6f28a1fe96c60e1a920a23020 100644 (file)
@@ -27,7 +27,7 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::ext::base::SyntaxExtension;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::visit;
 use syntax::{span_err, span_fatal};
 use syntax_pos::{Span, DUMMY_SP};
@@ -650,9 +650,8 @@ fn load_derive_macros(&mut self, root: &CrateRoot, dylib: Option<PathBuf>, span:
     /// SVH and DefIndex of the registrar function.
     pub fn find_plugin_registrar(&mut self,
                                  span: Span,
-                                 name: &str)
+                                 name: Symbol)
                                  -> Option<(PathBuf, CrateDisambiguator)> {
-        let name = Symbol::intern(name);
         let ekrate = self.read_extension_crate(span, name, name);
 
         if ekrate.target_only {
@@ -704,7 +703,7 @@ fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
         let desired_strategy = self.sess.panic_strategy();
         let mut runtime_found = false;
         let mut needs_panic_runtime = attr::contains_name(&krate.attrs,
-                                                          "needs_panic_runtime");
+                                                          sym::needs_panic_runtime);
 
         self.cstore.iter_crate_data(|cnum, data| {
             needs_panic_runtime = needs_panic_runtime ||
@@ -837,7 +836,7 @@ fn inject_sanitizer_runtime(&mut self) {
 
             let mut uses_std = false;
             self.cstore.iter_crate_data(|_, data| {
-                if data.name == "std" {
+                if data.name == sym::std {
                     uses_std = true;
                 }
             });
@@ -898,7 +897,7 @@ fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
         // about through the `#![needs_allocator]` attribute and is typically
         // written down in liballoc.
         let mut needs_allocator = attr::contains_name(&krate.attrs,
-                                                      "needs_allocator");
+                                                      sym::needs_allocator);
         self.cstore.iter_crate_data(|_, data| {
             needs_allocator = needs_allocator || data.root.needs_allocator;
         });
@@ -964,7 +963,7 @@ fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
         // allocator. At this point our allocator request is typically fulfilled
         // by the standard library, denoted by the `#![default_lib_allocator]`
         // attribute.
-        let mut has_default = attr::contains_name(&krate.attrs, "default_lib_allocator");
+        let mut has_default = attr::contains_name(&krate.attrs, sym::default_lib_allocator);
         self.cstore.iter_crate_data(|_, data| {
             if data.root.has_default_lib_allocator {
                 has_default = true;
@@ -987,7 +986,7 @@ fn has_global_allocator(krate: &ast::Crate) -> bool {
 
             impl<'ast> visit::Visitor<'ast> for Finder {
                 fn visit_item(&mut self, i: &'ast ast::Item) {
-                    if attr::contains_name(&i.attrs, "global_allocator") {
+                    if attr::contains_name(&i.attrs, sym::global_allocator) {
                         self.0 = true;
                     }
                     visit::walk_item(self, i)
@@ -1065,7 +1064,7 @@ pub fn process_extern_crate(
                     }
                     None => item.ident.name,
                 };
-                let dep_kind = if attr::contains_name(&item.attrs, "no_link") {
+                let dep_kind = if attr::contains_name(&item.attrs, sym::no_link) {
                     DepKind::UnexportedMacrosOnly
                 } else {
                     DepKind::Explicit
index dfeaeca323f8e7233c51fae78cf5964bfee74896..087256a971056ba410d58fdf9fe7b357e277ae55 100644 (file)
@@ -31,7 +31,7 @@
 use syntax::edition::Edition;
 use syntax::parse::source_file_to_stream;
 use syntax::parse::parser::emit_unclosed_delims;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::{Span, NO_EXPANSION, FileName};
 use rustc_data_structures::bit_set::BitSet;
 
@@ -432,7 +432,7 @@ pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
         let data = self.get_crate_data(id.krate);
         if let Some(ref proc_macros) = data.proc_macros {
             return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone());
-        } else if data.name == "proc_macro" && data.item_name(id.index) == "quote" {
+        } else if data.name == sym::proc_macro && data.item_name(id.index) == "quote" {
             use syntax::ext::base::SyntaxExtension;
             use syntax_ext::proc_macro_impl::BangProcMacro;
 
index 4b9db466da84307e4d4d55aca13032d5ddc47180..e950c2815e9b4547f60a0ecf25b4a9b0964bad76 100644 (file)
@@ -29,7 +29,7 @@
 use syntax::attr;
 use syntax::ast::{self, Ident};
 use syntax::source_map;
-use syntax::symbol::InternedString;
+use syntax::symbol::{InternedString, sym};
 use syntax::ext::base::{MacroKind, SyntaxExtension};
 use syntax::ext::hygiene::Mark;
 use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION};
@@ -841,7 +841,7 @@ pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Sessio
                                 // for other constructors correct visibilities
                                 // were already encoded in metadata.
                                 let attrs = self.get_item_attrs(def_id.index, sess);
-                                if attr::contains_name(&attrs, "non_exhaustive") {
+                                if attr::contains_name(&attrs, sym::non_exhaustive) {
                                     let crate_def_id = self.local_def_id(CRATE_DEF_INDEX);
                                     vis = ty::Visibility::Restricted(crate_def_id);
                                 }
index 0946dad53203dc7e8ace26ac69b2e09511fc7023..0ac03526832b7506c969c00e20318f4008c64157 100644 (file)
@@ -33,7 +33,7 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::source_map::Spanned;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax_pos::{self, hygiene, FileName, SourceFile, Span};
 use log::{debug, trace};
 
@@ -469,7 +469,7 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
 
         let attrs = tcx.hir().krate_attrs();
         let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
-        let has_default_lib_allocator = attr::contains_name(&attrs, "default_lib_allocator");
+        let has_default_lib_allocator = attr::contains_name(&attrs, sym::default_lib_allocator);
         let has_global_allocator = *tcx.sess.has_global_allocator.get();
         let has_panic_handler = *tcx.sess.has_panic_handler.try_get().unwrap_or(&false);
 
@@ -496,13 +496,13 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
             } else {
                 None
             },
-            compiler_builtins: attr::contains_name(&attrs, "compiler_builtins"),
-            needs_allocator: attr::contains_name(&attrs, "needs_allocator"),
-            needs_panic_runtime: attr::contains_name(&attrs, "needs_panic_runtime"),
-            no_builtins: attr::contains_name(&attrs, "no_builtins"),
-            panic_runtime: attr::contains_name(&attrs, "panic_runtime"),
-            profiler_runtime: attr::contains_name(&attrs, "profiler_runtime"),
-            sanitizer_runtime: attr::contains_name(&attrs, "sanitizer_runtime"),
+            compiler_builtins: attr::contains_name(&attrs, sym::compiler_builtins),
+            needs_allocator: attr::contains_name(&attrs, sym::needs_allocator),
+            needs_panic_runtime: attr::contains_name(&attrs, sym::needs_panic_runtime),
+            no_builtins: attr::contains_name(&attrs, sym::no_builtins),
+            panic_runtime: attr::contains_name(&attrs, sym::panic_runtime),
+            profiler_runtime: attr::contains_name(&attrs, sym::profiler_runtime),
+            sanitizer_runtime: attr::contains_name(&attrs, sym::sanitizer_runtime),
 
             crate_deps,
             dylib_dependency_formats,
index 6741b5235db36249d82a92ed48f94087203d4784..f4682465a659ae32bbaaba0dc4799ab9b6f5f3fa 100644 (file)
@@ -2,6 +2,7 @@
 use rustc::hir;
 use rustc::ty::TyCtxt;
 use rustc_target::spec::abi::Abi;
+use syntax::symbol::sym;
 
 pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec<String> {
     let mut collector = Collector {
@@ -10,7 +11,7 @@ pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec<String> {
     tcx.hir().krate().visit_all_item_likes(&mut collector);
 
     for attr in tcx.hir().krate().attrs.iter() {
-        if attr.path == "link_args" {
+        if attr.path == sym::link_args {
             if let Some(linkarg) = attr.value_str() {
                 collector.add_link_args(&linkarg.as_str());
             }
@@ -37,7 +38,7 @@ fn visit_item(&mut self, it: &'tcx hir::Item) {
         }
 
         // First, add all of the custom #[link_args] attributes
-        for m in it.attrs.iter().filter(|a| a.check_name("link_args")) {
+        for m in it.attrs.iter().filter(|a| a.check_name(sym::link_args)) {
             if let Some(linkarg) = m.value_str() {
                 self.add_link_args(&linkarg.as_str());
             }
index 116042c53fb9e2455e2c00bea4bde81fdc6ea256..7d7dd1061a959db19aa1b8571db02167691c78a2 100644 (file)
 use rustc::util::nodemap::FxHashMap;
 
 use errors::DiagnosticBuilder;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::struct_span_err;
 use syntax_pos::Span;
 use rustc_target::spec::{Target, TargetTriple};
@@ -408,7 +408,7 @@ pub fn report_errs(&mut self) -> ! {
                                            self.ident,
                                            add);
 
-            if (self.ident == "std" || self.ident == "core")
+            if (self.ident == sym::std || self.ident == sym::core)
                 && self.triple != TargetTriple::from_triple(config::host_triple()) {
                 err.note(&format!("the `{}` target may not be installed", self.triple));
             }
index e0665127c0fb012e76bd224d4cbaef0b8925270e..fee08f421549dc9811954d6af4ec85d84a282744 100644 (file)
@@ -8,7 +8,7 @@
 use syntax::attr;
 use syntax::source_map::Span;
 use syntax::feature_gate::{self, GateIssue};
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::{span_err, struct_span_err};
 
 pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec<NativeLibrary> {
@@ -47,7 +47,7 @@ fn visit_item(&mut self, it: &'tcx hir::Item) {
         }
 
         // Process all of the #[link(..)]-style arguments
-        for m in it.attrs.iter().filter(|a| a.check_name("link")) {
+        for m in it.attrs.iter().filter(|a| a.check_name(sym::link)) {
             let items = match m.meta_item_list() {
                 Some(item) => item,
                 None => continue,
@@ -62,7 +62,7 @@ fn visit_item(&mut self, it: &'tcx hir::Item) {
             let mut kind_specified = false;
 
             for item in items.iter() {
-                if item.check_name("kind") {
+                if item.check_name(sym::kind) {
                     kind_specified = true;
                     let kind = match item.value_str() {
                         Some(name) => name,
@@ -81,9 +81,9 @@ fn visit_item(&mut self, it: &'tcx hir::Item) {
                             cstore::NativeUnknown
                         }
                     };
-                } else if item.check_name("name") {
+                } else if item.check_name(sym::name) {
                     lib.name = item.value_str();
-                } else if item.check_name("cfg") {
+                } else if item.check_name(sym::cfg) {
                     let cfg = match item.meta_item_list() {
                         Some(list) => list,
                         None => continue, // skip like historical compilers
@@ -98,7 +98,7 @@ fn visit_item(&mut self, it: &'tcx hir::Item) {
                     } else {
                         self.tcx.sess.span_err(cfg[0].span(), "invalid argument for `cfg(..)`");
                     }
-                } else if item.check_name("wasm_import_module") {
+                } else if item.check_name(sym::wasm_import_module) {
                     match item.value_str() {
                         Some(s) => lib.wasm_import_module = Some(s),
                         None => {
@@ -156,7 +156,7 @@ fn register_native_lib(&mut self, span: Option<Span>, lib: NativeLibrary) {
         }
         if lib.cfg.is_some() && !self.tcx.features().link_cfg {
             feature_gate::emit_feature_err(&self.tcx.sess.parse_sess,
-                                           "link_cfg",
+                                           sym::link_cfg,
                                            span.unwrap(),
                                            GateIssue::Language,
                                            "is feature gated");
@@ -164,7 +164,7 @@ fn register_native_lib(&mut self, span: Option<Span>, lib: NativeLibrary) {
         if lib.kind == cstore::NativeStaticNobundle &&
            !self.tcx.features().static_nobundle {
             feature_gate::emit_feature_err(&self.tcx.sess.parse_sess,
-                                           "static_nobundle",
+                                           sym::static_nobundle,
                                            span.unwrap_or_else(|| syntax_pos::DUMMY_SP),
                                            GateIssue::Language,
                                            "kind=\"static-nobundle\" is feature gated");
@@ -181,7 +181,7 @@ fn process_command_line(&mut self) {
                 let any_duplicate = self.libs
                     .iter()
                     .filter_map(|lib| lib.name.as_ref())
-                    .any(|n| n == name);
+                    .any(|n| n.as_str() == *name);
                 if new_name.is_empty() {
                     self.tcx.sess.err(
                         &format!("an empty renaming target was specified for library `{}`",name));
@@ -212,7 +212,7 @@ fn process_command_line(&mut self) {
             // can move them to the end of the list below.
             let mut existing = self.libs.drain_filter(|lib| {
                 if let Some(lib_name) = lib.name {
-                    if lib_name == name as &str {
+                    if lib_name.as_str() == *name {
                         if let Some(k) = kind {
                             lib.kind = k;
                         }
index 8aa6456ebe77b8cbeef657d92c82d7238945b26b..1a1000f0bb41db9eaab73ab76d13ba7f562b213d 100644 (file)
@@ -20,6 +20,7 @@
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use syntax_pos::Span;
 use syntax::source_map::CompilerDesugaringKind;
+use syntax::symbol::sym;
 
 use super::borrow_set::BorrowData;
 use super::{MirBorrowckCtxt};
@@ -825,18 +826,21 @@ fn report_local_value_does_not_live_long_enough(
 
         let borrow_span = borrow_spans.var_or_use();
         if let BorrowExplanation::MustBeValidFor {
-            category: ConstraintCategory::Return,
+            category,
             span,
             ref opt_place_desc,
             from_closure: false,
             ..
         } = explanation {
-            return self.report_cannot_return_reference_to_local(
+            if let Some(diag) = self.try_report_cannot_return_reference_to_local(
                 borrow,
                 borrow_span,
                 span,
+                category,
                 opt_place_desc.as_ref(),
-            );
+            ) {
+                return diag;
+            }
         }
 
         let mut err = self.infcx.tcx.path_does_not_live_long_enough(
@@ -1014,17 +1018,20 @@ fn report_temporary_value_does_not_live_long_enough(
         );
 
         if let BorrowExplanation::MustBeValidFor {
-            category: ConstraintCategory::Return,
+            category,
             span,
             from_closure: false,
             ..
         } = explanation {
-            return self.report_cannot_return_reference_to_local(
+            if let Some(diag) = self.try_report_cannot_return_reference_to_local(
                 borrow,
                 proper_span,
                 span,
+                category,
                 None,
-            );
+            ) {
+                return diag;
+            }
         }
 
         let tcx = self.infcx.tcx;
@@ -1063,15 +1070,22 @@ fn report_temporary_value_does_not_live_long_enough(
         err
     }
 
-    fn report_cannot_return_reference_to_local(
+    fn try_report_cannot_return_reference_to_local(
         &self,
         borrow: &BorrowData<'tcx>,
         borrow_span: Span,
         return_span: Span,
+        category: ConstraintCategory,
         opt_place_desc: Option<&String>,
-    ) -> DiagnosticBuilder<'cx> {
+    ) -> Option<DiagnosticBuilder<'cx>> {
         let tcx = self.infcx.tcx;
 
+        let return_kind = match category {
+            ConstraintCategory::Return => "return",
+            ConstraintCategory::Yield => "yield",
+            _ => return None,
+        };
+
         // FIXME use a better heuristic than Spans
         let reference_desc = if return_span == self.mir.source_info(borrow.reserve_location).span {
             "reference to"
@@ -1109,7 +1123,7 @@ fn report_cannot_return_reference_to_local(
             let local = if let Place::Base(PlaceBase::Local(local)) = *root_place {
                 local
             } else {
-                bug!("report_cannot_return_reference_to_local: not a local")
+                bug!("try_report_cannot_return_reference_to_local: not a local")
             };
             match self.mir.local_kind(local) {
                 LocalKind::ReturnPointer | LocalKind::Temp => {
@@ -1130,6 +1144,7 @@ fn report_cannot_return_reference_to_local(
 
         let mut err = tcx.cannot_return_reference_to_local(
             return_span,
+            return_kind,
             reference_desc,
             &place_desc,
             Origin::Mir,
@@ -1139,7 +1154,7 @@ fn report_cannot_return_reference_to_local(
             err.span_label(borrow_span, note);
         }
 
-        err
+        Some(err)
     }
 
     fn report_escaping_closure_capture(
@@ -1839,7 +1854,7 @@ pub fn is_place_thread_local(&self, place: &Place<'tcx>) -> bool {
             PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })
         ) = place {
             let attrs = self.infcx.tcx.get_attrs(*def_id);
-            let is_thread_local = attrs.iter().any(|attr| attr.check_name("thread_local"));
+            let is_thread_local = attrs.iter().any(|attr| attr.check_name(sym::thread_local));
 
             debug!(
                 "is_place_thread_local: attrs={:?} is_thread_local={:?}",
index c64d4b4a531e046994e7a39e6ef4737c87e916c8..35efc6195be39709d4bfcdd273afe53e07a838bc 100644 (file)
@@ -310,9 +310,13 @@ pub(in crate::borrow_check) fn explain_why_borrow_contains_point(
                             opt_place_desc,
                         }
                     } else {
+                        debug!("explain_why_borrow_contains_point: \
+                                Could not generate a region name");
                         BorrowExplanation::Unexplained
                     }
                 } else {
+                    debug!("explain_why_borrow_contains_point: \
+                            Could not generate an error region vid");
                     BorrowExplanation::Unexplained
                 }
             }
index ad43c8ef66f42b5ecf5bc6d52ea46d618745d65a..fa490c108c8965f647caaa8a6c7509834d45fc14 100644 (file)
@@ -20,6 +20,7 @@
 use std::path::PathBuf;
 use std::rc::Rc;
 use std::str::FromStr;
+use syntax::symbol::sym;
 
 use self::mir_util::PassWhere;
 use polonius_engine::{Algorithm, Output};
@@ -280,7 +281,7 @@ fn dump_annotation<'a, 'gcx, 'tcx>(
 ) {
     let tcx = infcx.tcx;
     let base_def_id = tcx.closure_base_def_id(mir_def_id);
-    if !tcx.has_attr(base_def_id, "rustc_regions") {
+    if !tcx.has_attr(base_def_id, sym::rustc_regions) {
         return;
     }
 
index 4e197867bfb3ebb092076922939c9f74d0dd3e22..4ced31593b1ae6cc0264bcdb6bb160eb4c51eb99 100644 (file)
@@ -34,6 +34,7 @@
     MatchedAdtAndSegment(Span),
     AnonRegionFromUpvar(Span, String),
     AnonRegionFromOutput(Span, String, String),
+    AnonRegionFromYieldTy(Span, String),
 }
 
 impl RegionName {
@@ -48,7 +49,8 @@ impl RegionName {
             RegionNameSource::MatchedHirTy(..) |
             RegionNameSource::MatchedAdtAndSegment(..) |
             RegionNameSource::AnonRegionFromUpvar(..) |
-            RegionNameSource::AnonRegionFromOutput(..) => false,
+            RegionNameSource::AnonRegionFromOutput(..) |
+            RegionNameSource::AnonRegionFromYieldTy(..) => false,
         }
     }
 
@@ -105,6 +107,12 @@ impl RegionName {
                     format!("return type{} is {}", mir_description, type_name),
                 );
             },
+            RegionNameSource::AnonRegionFromYieldTy(span, type_name) => {
+                diag.span_label(
+                    *span,
+                    format!("yield type is {}", type_name),
+                );
+            }
             RegionNameSource::Static => {},
         }
     }
@@ -170,6 +178,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 self.give_name_if_anonymous_region_appears_in_output(
                     infcx, mir, mir_def_id, fr, counter,
                 )
+            })
+            .or_else(|| {
+                self.give_name_if_anonymous_region_appears_in_yield_ty(
+                    infcx, mir, mir_def_id, fr, counter,
+                )
             });
 
         debug!("give_region_a_name: gave name {:?}", value);
@@ -676,10 +689,7 @@ fn give_name_if_anonymous_region_appears_in_output(
             "give_name_if_anonymous_region_appears_in_output: return_ty = {:?}",
             return_ty
         );
-        if !infcx
-            .tcx
-            .any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr)
-        {
+        if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) {
             return None;
         }
 
@@ -724,6 +734,57 @@ fn give_name_if_anonymous_region_appears_in_output(
         })
     }
 
+    fn give_name_if_anonymous_region_appears_in_yield_ty(
+        &self,
+        infcx: &InferCtxt<'_, '_, 'tcx>,
+        mir: &Mir<'tcx>,
+        mir_def_id: DefId,
+        fr: RegionVid,
+        counter: &mut usize,
+    ) -> Option<RegionName> {
+        // Note: generators from `async fn` yield `()`, so we don't have to
+        // worry about them here.
+        let yield_ty = self.universal_regions.yield_ty?;
+        debug!(
+            "give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}",
+            yield_ty,
+        );
+
+        let tcx = infcx.tcx;
+
+        if !tcx.any_free_region_meets(&yield_ty, |r| r.to_region_vid() == fr) {
+            return None;
+        }
+
+        let mut highlight = RegionHighlightMode::default();
+        highlight.highlighting_region_vid(fr, *counter);
+        let type_name = infcx.extract_type_name(&yield_ty, Some(highlight));
+
+        let mir_node_id = tcx.hir().as_local_node_id(mir_def_id).expect("non-local mir");
+
+        let yield_span = match tcx.hir().get(mir_node_id) {
+            hir::Node::Expr(hir::Expr {
+                node: hir::ExprKind::Closure(_, _, _, span, _),
+                ..
+            }) => (
+                tcx.sess.source_map().end_point(*span)
+            ),
+            _ => mir.span,
+        };
+
+        debug!(
+            "give_name_if_anonymous_region_appears_in_yield_ty: \
+             type_name = {:?}, yield_span = {:?}",
+            yield_span,
+            type_name,
+        );
+
+        Some(RegionName {
+            name: self.synthesize_region_name(counter),
+            source: RegionNameSource::AnonRegionFromYieldTy(yield_span, type_name),
+        })
+    }
+
     /// Creates a synthetic region named `'1`, incrementing the
     /// counter.
     fn synthesize_region_name(&self, counter: &mut usize) -> InternedString {
index 83221aca6c5b389d1be75b8d04974be5ad941ad6..a9d23a0afeabcc3a6ef79a0fd9ddd1ccea0ac1ad 100644 (file)
@@ -1,4 +1,5 @@
 use syntax::ast::{self, MetaItem};
+use syntax::symbol::{Symbol, sym};
 
 use rustc_data_structures::bit_set::{BitSet, BitSetOperator, HybridBitSet};
 use rustc_data_structures::indexed_vec::Idx;
@@ -100,9 +101,9 @@ fn dataflow<P>(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> DebugFormatted {
     fn propagate(&mut self) { self.flow_state.propagate(); }
 }
 
-pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<MetaItem> {
+pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: Symbol) -> Option<MetaItem> {
     for attr in attrs {
-        if attr.check_name("rustc_mir") {
+        if attr.check_name(sym::rustc_mir) {
             let items = attr.meta_item_list();
             for item in items.iter().flat_map(|l| l.iter()) {
                 match item.meta_item() {
@@ -158,10 +159,8 @@ pub(crate) fn run<P>(self,
             return None;
         };
 
-        let print_preflow_to =
-            name_found(tcx.sess, attributes, "borrowck_graphviz_preflow");
-        let print_postflow_to =
-            name_found(tcx.sess, attributes, "borrowck_graphviz_postflow");
+        let print_preflow_to = name_found(tcx.sess, attributes, sym::borrowck_graphviz_preflow);
+        let print_postflow_to = name_found(tcx.sess, attributes, sym::borrowck_graphviz_postflow);
 
         let mut mbcx = DataflowBuilder {
             def_id,
index 7aed0bace8c0b0e0be6e3847de355a6927df8e35..e8070b21bb8c7d9e0350fc244b391ca9439dae6a 100644 (file)
@@ -16,7 +16,7 @@
 use rustc::ty::layout::VariantIdx;
 use syntax::ast;
 use syntax::attr;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use rustc::hir;
 use crate::hair::constant::{lit_to_const, LitToConstError};
 
@@ -67,7 +67,7 @@ pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
         // Some functions always have overflow checks enabled,
         // however, they may not get codegen'd, depending on
         // the settings for the crate they are codegened in.
-        let mut check_overflow = attr::contains_name(attrs, "rustc_inherit_overflow_checks");
+        let mut check_overflow = attr::contains_name(attrs, sym::rustc_inherit_overflow_checks);
 
         // Respect -C overflow-checks.
         check_overflow |= tcx.sess.overflow_checks();
index 01b1780a2054fb8752203ac1ed65d4f1c2b86706..0576bb53d8f4219268ff2e1eb02dd97abe500723 100644 (file)
@@ -27,6 +27,7 @@
 use std::fmt;
 use syntax::ast;
 use syntax::ptr::P;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 #[derive(Clone, Debug)]
@@ -978,7 +979,7 @@ fn const_to_pat(
                 self.tcx.sess.span_err(span, "cannot use unions in constant patterns");
                 PatternKind::Wild
             }
-            ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, "structural_match") => {
+            ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, sym::structural_match) => {
                 let path = self.tcx.def_path_str(adt_def.did);
                 let msg = format!(
                     "to use a constant of type `{}` in a pattern, \
@@ -990,7 +991,7 @@ fn const_to_pat(
                 PatternKind::Wild
             }
             ty::Ref(_, ty::TyS { sty: ty::Adt(adt_def, _), .. }, _)
-            if !self.tcx.has_attr(adt_def.did, "structural_match") => {
+            if !self.tcx.has_attr(adt_def.did, sym::structural_match) => {
                 // HACK(estebank): Side-step ICE #53708, but anything other than erroring here
                 // would be wrong. Returnging `PatternKind::Wild` is not technically correct.
                 let path = self.tcx.def_path_str(adt_def.did);
index 58e474658ead5748000fd755df5b50deb2a9b5b9..2512525b4bb7e56ffff5caf4384f65870625d77d 100644 (file)
@@ -2,6 +2,7 @@
 use rustc::ty::layout::{self, TyLayout, Size};
 use rustc::ty::adjustment::{PointerCast};
 use syntax::ast::{FloatTy, IntTy, UintTy};
+use syntax::symbol::sym;
 
 use rustc_apfloat::ieee::{Single, Double};
 use rustc::mir::interpret::{
@@ -76,9 +77,8 @@ pub fn cast(
                 // The src operand does not matter, just its type
                 match src.layout.ty.sty {
                     ty::FnDef(def_id, substs) => {
-                        if self.tcx.has_attr(def_id, "rustc_args_required_const") {
-                            bug!("reifying a fn ptr that requires \
-                                    const arguments");
+                        if self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
+                            bug!("reifying a fn ptr that requires const arguments");
                         }
                         let instance: EvalResult<'tcx, _> = ty::Instance::resolve(
                             *self.tcx,
index 078b347fb3f6be0fc8949734cc5f4d25670bb8ed..fab07a2290eb5a31efc5bebf8a33aede8a6c7269 100644 (file)
@@ -12,7 +12,7 @@
 use rustc::mir::*;
 use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext};
 
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 
 use std::ops::Bound;
 
@@ -612,7 +612,7 @@ fn report_unused_unsafe(tcx: TyCtxt<'_, '_, '_>,
 fn builtin_derive_def_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option<DefId> {
     debug!("builtin_derive_def_id({:?})", def_id);
     if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
-        if tcx.has_attr(impl_def_id, "automatically_derived") {
+        if tcx.has_attr(impl_def_id, sym::automatically_derived) {
             debug!("builtin_derive_def_id({:?}) - is {:?}", def_id, impl_def_id);
             Some(impl_def_id)
         } else {
index 9a39e071721147ac0c3e80f897f64d446d929c65..579f75ba516571a9ece7da2a60285c10efd77191 100644 (file)
@@ -22,6 +22,7 @@
 use rustc::session::config::nightly_options;
 use syntax::ast::LitKind;
 use syntax::feature_gate::{emit_feature_err, GateIssue};
+use syntax::symbol::sym;
 use syntax_pos::{Span, DUMMY_SP};
 
 use std::fmt;
@@ -380,8 +381,8 @@ fn in_static(cx: &ConstCx<'_, 'tcx>, static_: &Static<'tcx>) -> bool {
 
                 !allowed ||
                     cx.tcx.get_attrs(def_id).iter().any(
-                        |attr| attr.check_name("thread_local"
-                    ))
+                        |attr| attr.check_name(sym::thread_local)
+                    )
             }
         }
     }
@@ -939,7 +940,7 @@ fn visit_place(&mut self,
                 if self.tcx
                        .get_attrs(def_id)
                        .iter()
-                       .any(|attr| attr.check_name("thread_local")) {
+                       .any(|attr| attr.check_name(sym::thread_local)) {
                     if self.mode != Mode::Fn {
                         span_err!(self.tcx.sess, self.span, E0625,
                                   "thread-local statics cannot be \
@@ -994,7 +995,7 @@ fn visit_place(&mut self,
                                 if let ty::RawPtr(_) = base_ty.sty {
                                     if !self.tcx.features().const_raw_ptr_deref {
                                         emit_feature_err(
-                                            &self.tcx.sess.parse_sess, "const_raw_ptr_deref",
+                                            &self.tcx.sess.parse_sess, sym::const_raw_ptr_deref,
                                             self.span, GateIssue::Language,
                                             &format!(
                                                 "dereferencing raw pointers in {}s is unstable",
@@ -1018,7 +1019,7 @@ fn visit_place(&mut self,
                                     Mode::ConstFn => {
                                         if !self.tcx.features().const_fn_union {
                                             emit_feature_err(
-                                                &self.tcx.sess.parse_sess, "const_fn_union",
+                                                &self.tcx.sess.parse_sess, sym::const_fn_union,
                                                 self.span, GateIssue::Language,
                                                 "unions in const fn are unstable",
                                             );
@@ -1123,7 +1124,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
                             // in const fn and constants require the feature gate
                             // FIXME: make it unsafe inside const fn and constants
                             emit_feature_err(
-                                &self.tcx.sess.parse_sess, "const_raw_ptr_to_usize_cast",
+                                &self.tcx.sess.parse_sess, sym::const_raw_ptr_to_usize_cast,
                                 self.span, GateIssue::Language,
                                 &format!(
                                     "casting pointers to integers in {}s is unstable",
@@ -1149,7 +1150,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
                         // FIXME: make it unsafe to use these operations
                         emit_feature_err(
                             &self.tcx.sess.parse_sess,
-                            "const_compare_raw_pointers",
+                            sym::const_compare_raw_pointers,
                             self.span,
                             GateIssue::Language,
                             &format!("comparing raw pointers inside {}", self.mode),
@@ -1210,7 +1211,7 @@ fn visit_terminator_kind(&mut self,
                                         // const eval transmute calls only with the feature gate
                                         if !self.tcx.features().const_transmute {
                                             emit_feature_err(
-                                                &self.tcx.sess.parse_sess, "const_transmute",
+                                                &self.tcx.sess.parse_sess, sym::const_transmute,
                                                 self.span, GateIssue::Language,
                                                 &format!("The use of std::mem::transmute() \
                                                 is gated in {}s", self.mode));
@@ -1249,7 +1250,7 @@ fn visit_terminator_kind(&mut self,
                                         // Don't allow panics in constants without the feature gate.
                                         emit_feature_err(
                                             &self.tcx.sess.parse_sess,
-                                            "const_panic",
+                                            sym::const_panic,
                                             self.span,
                                             GateIssue::Language,
                                             &format!("panicking in {}s is unstable", self.mode),
@@ -1260,7 +1261,7 @@ fn visit_terminator_kind(&mut self,
                                     // Check `#[unstable]` const fns or `#[rustc_const_unstable]`
                                     // functions without the feature gate active in this crate in
                                     // order to report a better error message than the one below.
-                                    if !self.span.allows_unstable(&feature.as_str()) {
+                                    if !self.span.allows_unstable(feature) {
                                         let mut err = self.tcx.sess.struct_span_err(self.span,
                                             &format!("`{}` is not yet stable as a const fn",
                                                     self.tcx.def_path_str(def_id)));
@@ -1592,7 +1593,7 @@ fn run_pass<'a, 'tcx>(&self,
         if mode == Mode::Static {
             // `#[thread_local]` statics don't have to be `Sync`.
             for attr in &tcx.get_attrs(def_id)[..] {
-                if attr.check_name("thread_local") {
+                if attr.check_name(sym::thread_local) {
                     return;
                 }
             }
@@ -1616,7 +1617,7 @@ fn run_pass<'a, 'tcx>(&self,
 
 fn args_required_const(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option<FxHashSet<usize>> {
     let attrs = tcx.get_attrs(def_id);
-    let attr = attrs.iter().find(|a| a.check_name("rustc_args_required_const"))?;
+    let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?;
     let mut ret = FxHashSet::default();
     for meta in attr.meta_item_list()? {
         match meta.literal()?.node {
index 246f876235d71c384a782fbf24ec7523d0d14581..815821f6ff0337eb6bf72906485e398917d9d41a 100644 (file)
@@ -1,5 +1,6 @@
 use rustc_target::spec::abi::{Abi};
 use syntax::ast;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 use rustc::ty::{self, TyCtxt};
@@ -27,7 +28,7 @@ impl MirPass for SanityCheck {
     fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                           src: MirSource<'tcx>, mir: &mut Mir<'tcx>) {
         let def_id = src.def_id();
-        if !tcx.has_attr(def_id, "rustc_mir") {
+        if !tcx.has_attr(def_id, sym::rustc_mir) {
             debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
             return;
         } else {
@@ -52,16 +53,16 @@ fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         DefinitelyInitializedPlaces::new(tcx, mir, &mdpe),
                         |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
 
-        if has_rustc_mir_with(&attributes, "rustc_peek_maybe_init").is_some() {
+        if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_init).is_some() {
             sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_inits);
         }
-        if has_rustc_mir_with(&attributes, "rustc_peek_maybe_uninit").is_some() {
+        if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_uninit).is_some() {
             sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_uninits);
         }
-        if has_rustc_mir_with(&attributes, "rustc_peek_definite_init").is_some() {
+        if has_rustc_mir_with(&attributes, sym::rustc_peek_definite_init).is_some() {
             sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_def_inits);
         }
-        if has_rustc_mir_with(&attributes, "stop_after_dataflow").is_some() {
+        if has_rustc_mir_with(&attributes, sym::stop_after_dataflow).is_some() {
             tcx.sess.fatal("stop_after_dataflow ended compilation");
         }
     }
index 4563c9f18a3e4fa41dbb353bd826a1476485342d..a5dfb736b819c08762e55271fb496a69da20ad3b 100644 (file)
@@ -634,6 +634,7 @@ fn path_does_not_live_long_enough(
     fn cannot_return_reference_to_local(
         self,
         span: Span,
+        return_kind: &str,
         reference_desc: &str,
         path_desc: &str,
         o: Origin,
@@ -642,7 +643,8 @@ fn cannot_return_reference_to_local(
             self,
             span,
             E0515,
-            "cannot return {REFERENCE} {LOCAL}{OGN}",
+            "cannot {RETURN} {REFERENCE} {LOCAL}{OGN}",
+            RETURN=return_kind,
             REFERENCE=reference_desc,
             LOCAL=path_desc,
             OGN = o
@@ -650,7 +652,7 @@ fn cannot_return_reference_to_local(
 
         err.span_label(
             span,
-            format!("returns a {} data owned by the current function", reference_desc),
+            format!("{}s a {} data owned by the current function", return_kind, reference_desc),
         );
 
         self.cancel_if_wrong_origin(err, o)
index 6cb3161382af2102ccdeb604436d360e388988b0..2bea1db841ae918db916e9e2ba15f6f67255ddf9 100644 (file)
@@ -15,7 +15,7 @@
 use syntax::ast::*;
 use syntax::attr;
 use syntax::source_map::Spanned;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax::ptr::P;
 use syntax::visit::{self, Visitor};
 use syntax::{span_err, struct_span_err, walk_list};
@@ -54,21 +54,21 @@ struct AstValidator<'a> {
     has_proc_macro_decls: bool,
     has_global_allocator: bool,
 
-    // Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
-    // Nested `impl Trait` _is_ allowed in associated type position,
-    // e.g `impl Iterator<Item=impl Debug>`
+    /// Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
+    /// Nested `impl Trait` _is_ allowed in associated type position,
+    /// e.g `impl Iterator<Item=impl Debug>`
     outer_impl_trait: Option<OuterImplTrait>,
 
-    // Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
-    // or `Foo::Bar<impl Trait>`
+    /// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
+    /// or `Foo::Bar<impl Trait>`
     is_impl_trait_banned: bool,
 
-    // rust-lang/rust#57979: the ban of nested `impl Trait` was buggy
-    // until PRs #57730 and #57981 landed: it would jump directly to
-    // walk_ty rather than visit_ty (or skip recurring entirely for
-    // impl trait in projections), and thus miss some cases. We track
-    // whether we should downgrade to a warning for short-term via
-    // these booleans.
+    /// rust-lang/rust#57979: the ban of nested `impl Trait` was buggy
+    /// until PRs #57730 and #57981 landed: it would jump directly to
+    /// walk_ty rather than visit_ty (or skip recurring entirely for
+    /// impl trait in projections), and thus miss some cases. We track
+    /// whether we should downgrade to a warning for short-term via
+    /// these booleans.
     warning_period_57979_didnt_record_next_impl_trait: bool,
     warning_period_57979_impl_trait_in_proj: bool,
 }
@@ -565,7 +565,7 @@ fn visit_item(&mut self, item: &'a Item) {
             self.has_proc_macro_decls = true;
         }
 
-        if attr::contains_name(&item.attrs, "global_allocator") {
+        if attr::contains_name(&item.attrs, sym::global_allocator) {
             self.has_global_allocator = true;
         }
 
@@ -676,8 +676,8 @@ fn visit_item(&mut self, item: &'a Item) {
             }
             ItemKind::Mod(_) => {
                 // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
-                attr::first_attr_value_str_by_name(&item.attrs, "path");
-                if attr::contains_name(&item.attrs, "warn_directory_ownership") {
+                attr::first_attr_value_str_by_name(&item.attrs, sym::path);
+                if attr::contains_name(&item.attrs, sym::warn_directory_ownership) {
                     let lint = lint::builtin::LEGACY_DIRECTORY_OWNERSHIP;
                     let msg = "cannot declare a new module at this location";
                     self.session.buffer_lint(lint, item.id, item.span, msg);
index 7041a5593abbfe861d664f081f1fd74be0cdd81c..dea5774aa6eb7c64a00f39545bcf1aece4f9c293 100644 (file)
@@ -12,6 +12,7 @@
 use rustc::ty::Ty;
 use rustc::ty::TyCtxt;
 use syntax::ast::Attribute;
+use syntax::symbol::sym;
 
 pub fn test_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     if tcx.features().rustc_attrs {
@@ -32,7 +33,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
 
         if let ItemKind::Ty(..) = item.node {
             for attr in self.tcx.get_attrs(item_def_id).iter() {
-                if attr.check_name("rustc_layout") {
+                if attr.check_name(sym::rustc_layout) {
                     self.dump_layout_of(item_def_id, item, attr);
                 }
             }
@@ -54,26 +55,26 @@ fn dump_layout_of(&self, item_def_id: DefId, item: &hir::Item, attr: &Attribute)
                 // The `..` are the names of fields to dump.
                 let meta_items = attr.meta_item_list().unwrap_or_default();
                 for meta_item in meta_items {
-                    match meta_item.name_or_empty().get() {
-                        "abi" => {
+                    match meta_item.name_or_empty() {
+                        sym::abi => {
                             self.tcx
                                 .sess
                                 .span_err(item.span, &format!("abi: {:?}", ty_layout.abi));
                         }
 
-                        "align" => {
+                        sym::align => {
                             self.tcx
                                 .sess
                                 .span_err(item.span, &format!("align: {:?}", ty_layout.align));
                         }
 
-                        "size" => {
+                        sym::size => {
                             self.tcx
                                 .sess
                                 .span_err(item.span, &format!("size: {:?}", ty_layout.size));
                         }
 
-                        "homogeneous_aggregate" => {
+                        sym::homogeneous_aggregate => {
                             self.tcx.sess.span_err(
                                 item.span,
                                 &format!(
index 2d35a0de7953f4193a0cf1c86c4aa016a82381ba..37917aaa4a80f4c2c7b39adcf6a2edee2319d60f 100644 (file)
@@ -25,6 +25,7 @@
 use rustc::ty::subst::{InternalSubsts, SubstsRef};
 use rustc::util::nodemap::{ItemLocalSet, HirIdSet};
 use rustc::hir;
+use syntax::symbol::sym;
 use syntax_pos::{Span, DUMMY_SP};
 use log::debug;
 use Promotability::*;
@@ -335,7 +336,7 @@ fn check_expr_kind<'a, 'tcx>(
 
                     if v.in_static {
                         for attr in &v.tcx.get_attrs(did)[..] {
-                            if attr.check_name("thread_local") {
+                            if attr.check_name(sym::thread_local) {
                                 debug!("Reference to Static(id={:?}) is unpromotable \
                                        due to a #[thread_local] attribute", did);
                                 return NotPromotable;
index 31018a7cd7a3ca7969627a4fe3038687c32d8e57..8259419c64aeb17d67baed9a87ce70d6e243b374 100644 (file)
@@ -1,6 +1,7 @@
 //! Used by `rustc` when compiling a plugin crate.
 
 use syntax::attr;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir;
@@ -15,8 +16,7 @@ struct RegistrarFinder {
 impl<'v> ItemLikeVisitor<'v> for RegistrarFinder {
     fn visit_item(&mut self, item: &hir::Item) {
         if let hir::ItemKind::Fn(..) = item.node {
-            if attr::contains_name(&item.attrs,
-                                   "plugin_registrar") {
+            if attr::contains_name(&item.attrs, sym::plugin_registrar) {
                 self.registrars.push((item.hir_id, item.span));
             }
         }
index 8b86bddb29f4e25264bbcae11e096e34f2fab62e..680bdcc4bbe9763f687b3c97685198f8705500ff 100644 (file)
@@ -11,6 +11,7 @@
 use std::path::PathBuf;
 use syntax::ast;
 use syntax::span_err;
+use syntax::symbol::{Symbol, keywords, sym};
 use syntax_pos::{Span, DUMMY_SP};
 
 /// Pointer to a registrar function.
@@ -45,7 +46,7 @@ pub fn load_plugins(sess: &Session,
     // the feature enabled will result in an error later...
     if sess.features_untracked().plugin {
         for attr in &krate.attrs {
-            if !attr.check_name("plugin") {
+            if !attr.check_name(sym::plugin) {
                 continue;
             }
 
@@ -57,9 +58,9 @@ pub fn load_plugins(sess: &Session,
             for plugin in plugins {
                 // plugins must have a name and can't be key = value
                 let name = plugin.name_or_empty();
-                if !name.is_empty() && !plugin.is_value_str() {
+                if name != keywords::Invalid.name() && !plugin.is_value_str() {
                     let args = plugin.meta_item_list().map(ToOwned::to_owned);
-                    loader.load_plugin(plugin.span(), &name, args.unwrap_or_default());
+                    loader.load_plugin(plugin.span(), name, args.unwrap_or_default());
                 } else {
                     call_malformed_plugin_attribute(sess, attr.span);
                 }
@@ -69,7 +70,7 @@ pub fn load_plugins(sess: &Session,
 
     if let Some(plugins) = addl_plugins {
         for plugin in plugins {
-            loader.load_plugin(DUMMY_SP, &plugin, vec![]);
+            loader.load_plugin(DUMMY_SP, Symbol::intern(&plugin), vec![]);
         }
     }
 
@@ -85,7 +86,7 @@ fn new(sess: &'a Session, cstore: &'a CStore, crate_name: &str) -> Self {
         }
     }
 
-    fn load_plugin(&mut self, span: Span, name: &str, args: Vec<ast::NestedMetaItem>) {
+    fn load_plugin(&mut self, span: Span, name: Symbol, args: Vec<ast::NestedMetaItem>) {
         let registrar = self.reader.find_plugin_registrar(span, name);
 
         if let Some((lib, disambiguator)) = registrar {
index 5c5b6f232b271140ac6fe5c9d7a8e0cd6fa258dd..c2d1d5fa65af299b242b708009a9d0f0878499c8 100644 (file)
@@ -7,7 +7,7 @@
 use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT, IdentTT};
 use syntax::ext::base::MacroExpanderFn;
 use syntax::ext::hygiene;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::ast;
 use syntax::feature_gate::AttributeType;
 use syntax_pos::Span;
@@ -49,7 +49,7 @@ pub struct Registry<'a> {
     pub llvm_passes: Vec<String>,
 
     #[doc(hidden)]
-    pub attributes: Vec<(String, AttributeType)>,
+    pub attributes: Vec<(Symbol, AttributeType)>,
 }
 
 impl<'a> Registry<'a> {
@@ -86,7 +86,7 @@ pub fn args<'b>(&'b self) -> &'b [ast::NestedMetaItem] {
     ///
     /// This is the most general hook into `libsyntax`'s expansion behavior.
     pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
-        if name == "macro_rules" {
+        if name == sym::macro_rules {
             panic!("user-defined macros may not be named `macro_rules`");
         }
         self.syntax_exts.push((name, match extension {
@@ -169,7 +169,7 @@ pub fn register_llvm_pass(&mut self, name: &str) {
     /// Registered attributes will bypass the `custom_attribute` feature gate.
     /// `Whitelisted` attributes will additionally not trigger the `unused_attribute`
     /// lint. `CrateLevel` attributes will not be allowed on anything other than a crate.
-    pub fn register_attribute(&mut self, name: String, ty: AttributeType) {
+    pub fn register_attribute(&mut self, name: Symbol, ty: AttributeType) {
         self.attributes.push((name, ty));
     }
 }
index e561b387389e7dd244d34c67e79d17b0b5d81706..cd21713cddf97364da7657f09c16a375b416f452 100644 (file)
@@ -27,7 +27,7 @@
 use rustc_data_structures::sync::Lrc;
 use syntax::ast::Ident;
 use syntax::attr;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax_pos::Span;
 
 use std::{cmp, fmt, mem};
@@ -260,7 +260,8 @@ fn def_id_visibility<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                                 ctor_vis = ty::Visibility::Restricted(
                                     DefId::local(CRATE_DEF_INDEX));
                                 let attrs = tcx.get_attrs(variant.def_id);
-                                span = attr::find_by_name(&attrs, "non_exhaustive").unwrap().span;
+                                span = attr::find_by_name(&attrs, sym::non_exhaustive)
+                                    .unwrap().span;
                                 descr = "crate-visible";
                             }
 
@@ -291,7 +292,7 @@ fn def_id_visibility<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                                 if adt_def.non_enum_variant().is_field_list_non_exhaustive() {
                                     ctor_vis =
                                         ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
-                                    span = attr::find_by_name(&item.attrs, "non_exhaustive")
+                                    span = attr::find_by_name(&item.attrs, sym::non_exhaustive)
                                                 .unwrap().span;
                                     descr = "crate-visible";
                                 }
index 3c5760c746fc3dea4faa3f0bb154730376614726..f70ca6f859b98b71a41ae308681d300f273079a6 100644 (file)
@@ -37,7 +37,7 @@
 use syntax::parse::token::{self, Token};
 use syntax::span_err;
 use syntax::std_inject::injected_crate_name;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax::visit::{self, Visitor};
 
 use syntax_pos::{Span, DUMMY_SP};
@@ -257,7 +257,7 @@ fn build_reduced_graph_for_use_tree(
             }
             ast::UseTreeKind::Glob => {
                 let subclass = GlobImport {
-                    is_prelude: attr::contains_name(&item.attrs, "prelude_import"),
+                    is_prelude: attr::contains_name(&item.attrs, sym::prelude_import),
                     max_vis: Cell::new(ty::Visibility::Invisible),
                 };
                 self.add_import_directive(
@@ -369,7 +369,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent_scope: ParentScop
                 };
 
                 self.populate_module_if_necessary(module);
-                if injected_crate_name().map_or(false, |name| ident.name == name) {
+                if injected_crate_name().map_or(false, |name| ident.name.as_str() == name) {
                     self.injected_crate = Some(module);
                 }
 
@@ -427,7 +427,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent_scope: ParentScop
                 let module_kind = ModuleKind::Def(DefKind::Mod, def_id, ident.name);
                 let module = self.arenas.alloc_module(ModuleData {
                     no_implicit_prelude: parent.no_implicit_prelude || {
-                        attr::contains_name(&item.attrs, "no_implicit_prelude")
+                        attr::contains_name(&item.attrs, sym::no_implicit_prelude)
                     },
                     ..ModuleData::new(Some(parent), module_kind, def_id, expansion, item.span)
                 });
@@ -456,12 +456,12 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent_scope: ParentScop
 
                 // Functions introducing procedural macros reserve a slot
                 // in the macro namespace as well (see #52225).
-                if attr::contains_name(&item.attrs, "proc_macro") ||
-                   attr::contains_name(&item.attrs, "proc_macro_attribute") {
+                if attr::contains_name(&item.attrs, sym::proc_macro) ||
+                   attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
                     let res = Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), res.def_id());
                     self.define(parent, ident, MacroNS, (res, vis, sp, expansion));
                 }
-                if let Some(attr) = attr::find_by_name(&item.attrs, "proc_macro_derive") {
+                if let Some(attr) = attr::find_by_name(&item.attrs, sym::proc_macro_derive) {
                     if let Some(trait_attr) =
                             attr.meta_item_list().and_then(|list| list.get(0).cloned()) {
                         if let Some(ident) = trait_attr.ident() {
@@ -518,7 +518,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent_scope: ParentScop
 
                 let mut ctor_vis = vis;
 
-                let has_non_exhaustive = attr::contains_name(&item.attrs, "non_exhaustive");
+                let has_non_exhaustive = attr::contains_name(&item.attrs, sym::non_exhaustive);
 
                 // If the structure is marked as non_exhaustive then lower the visibility
                 // to within the crate.
@@ -599,7 +599,7 @@ fn build_reduced_graph_for_variant(&mut self,
         // If the variant is marked as non_exhaustive then lower the visibility to within the
         // crate.
         let mut ctor_vis = vis;
-        let has_non_exhaustive = attr::contains_name(&variant.node.attrs, "non_exhaustive");
+        let has_non_exhaustive = attr::contains_name(&variant.node.attrs, sym::non_exhaustive);
         if has_non_exhaustive && vis == ty::Visibility::Public {
             ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
         }
@@ -825,7 +825,7 @@ fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>,
         let mut import_all = None;
         let mut single_imports = Vec::new();
         for attr in &item.attrs {
-            if attr.check_name("macro_use") {
+            if attr.check_name(sym::macro_use) {
                 if self.current_module.parent.is_some() {
                     span_err!(self.session, item.span, E0468,
                         "an `extern crate` loading macros must be at the crate root");
@@ -908,7 +908,7 @@ fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>,
     /// Returns `true` if this attribute list contains `macro_use`.
     fn contains_macro_use(&mut self, attrs: &[ast::Attribute]) -> bool {
         for attr in attrs {
-            if attr.check_name("macro_escape") {
+            if attr.check_name(sym::macro_escape) {
                 let msg = "macro_escape is a deprecated synonym for macro_use";
                 let mut err = self.session.struct_span_warn(attr.span, msg);
                 if let ast::AttrStyle::Inner = attr.style {
@@ -916,7 +916,7 @@ fn contains_macro_use(&mut self, attrs: &[ast::Attribute]) -> bool {
                 } else {
                     err.emit();
                 }
-            } else if !attr.check_name("macro_use") {
+            } else if !attr.check_name(sym::macro_use) {
                 continue;
             }
 
index 18da89b9099a5c3f0bdbd62c1c5d5dc1df7a6f66..678f4c23d3e9ebf8e6ca9622df91b0d6d957774a 100644 (file)
@@ -43,7 +43,7 @@
 use syntax::ext::base::SyntaxExtension;
 use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
 use syntax::ext::base::MacroKind;
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
 use syntax::util::lev_distance::find_best_match_for_name;
 
 use syntax::visit::{self, FnKind, Visitor};
@@ -1812,8 +1812,8 @@ fn resolve_hir_path(
     fn resolve_str_path(
         &mut self,
         span: Span,
-        crate_root: Option<&str>,
-        components: &[&str],
+        crate_root: Option<Symbol>,
+        components: &[Symbol],
         is_value: bool
     ) -> hir::Path {
         let root = if crate_root.is_some() {
@@ -1825,7 +1825,7 @@ fn resolve_str_path(
             .chain(
                 crate_root.into_iter()
                     .chain(components.iter().cloned())
-                    .map(Ident::from_str)
+                    .map(Ident::with_empty_ctxt)
             ).map(|i| self.new_ast_path_segment(i)).collect::<Vec<_>>();
 
 
@@ -1964,7 +1964,7 @@ pub fn new(session: &'a Session,
             keywords::Invalid.name(),
         );
         let graph_root = arenas.alloc_module(ModuleData {
-            no_implicit_prelude: attr::contains_name(&krate.attrs, "no_implicit_prelude"),
+            no_implicit_prelude: attr::contains_name(&krate.attrs, sym::no_implicit_prelude),
             ..ModuleData::new(None, root_module_kind, root_def_id, Mark::root(), krate.span)
         });
         let mut module_map = FxHashMap::default();
@@ -1978,9 +1978,9 @@ pub fn new(session: &'a Session,
             session.opts.externs.iter().map(|kv| (Ident::from_str(kv.0), Default::default()))
                                        .collect();
 
-        if !attr::contains_name(&krate.attrs, "no_core") {
+        if !attr::contains_name(&krate.attrs, sym::no_core) {
             extern_prelude.insert(Ident::from_str("core"), Default::default());
-            if !attr::contains_name(&krate.attrs, "no_std") {
+            if !attr::contains_name(&krate.attrs, sym::no_std) {
                 extern_prelude.insert(Ident::from_str("std"), Default::default());
                 if session.rust_2018() {
                     extern_prelude.insert(Ident::from_str("meta"), Default::default());
index 79a92d595c2edc9ebc64213e20ad8faf7b2ae9d4..9f3e1c308f6379e9c591b7530381098459057b0a 100644 (file)
@@ -22,7 +22,7 @@
 use syntax::feature_gate::{
     feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES,
 };
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
 use syntax::visit::Visitor;
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax_pos::{Span, DUMMY_SP};
@@ -313,7 +313,8 @@ fn resolve_macro_to_res(
                             if !features.rustc_attrs {
                                 let msg = "unless otherwise specified, attributes with the prefix \
                                            `rustc_` are reserved for internal compiler diagnostics";
-                                self.report_unknown_attribute(path.span, &name, msg, "rustc_attrs");
+                                self.report_unknown_attribute(path.span, &name, msg,
+                                                              sym::rustc_attrs);
                             }
                         } else if !features.custom_attribute {
                             let msg = format!("The attribute `{}` is currently unknown to the \
@@ -323,7 +324,7 @@ fn resolve_macro_to_res(
                                 path.span,
                                 &name,
                                 &msg,
-                                "custom_attribute",
+                                sym::custom_attribute,
                             );
                         }
                     }
@@ -345,7 +346,7 @@ fn resolve_macro_to_res(
         Ok((res, self.get_macro(res)))
     }
 
-    fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: &str) {
+    fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: Symbol) {
         let mut err = feature_err(
             &self.session.parse_sess,
             feature,
@@ -693,7 +694,7 @@ struct Flags: u8 {
                 WhereToResolve::LegacyPluginHelpers => {
                     if (use_prelude || rust_2015) &&
                        self.session.plugin_attributes.borrow().iter()
-                                                     .any(|(name, _)| ident.name == &**name) {
+                                                     .any(|(name, _)| ident.name == *name) {
                         let binding = (Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper),
                                        ty::Visibility::Public, DUMMY_SP, Mark::root())
                                        .to_name_binding(self.arenas);
@@ -981,7 +982,7 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
                     let msg =
                         format!("cannot find {} `{}{}` in this scope", kind.descr(), ident, bang);
                     let mut err = self.session.struct_span_err(ident.span, &msg);
-                    self.suggest_macro_name(&ident.as_str(), kind, &mut err, ident.span);
+                    self.suggest_macro_name(ident.name, kind, &mut err, ident.span);
                     err.emit();
                 }
             }
@@ -1009,11 +1010,12 @@ fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>
         }
     }
 
-    fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
+    fn suggest_macro_name(&mut self, name: Symbol, kind: MacroKind,
                           err: &mut DiagnosticBuilder<'a>, span: Span) {
         // First check if this is a locally-defined bang macro.
         let suggestion = if let MacroKind::Bang = kind {
-            find_best_match_for_name(self.macro_names.iter().map(|ident| &ident.name), name, None)
+            find_best_match_for_name(
+                self.macro_names.iter().map(|ident| &ident.name), &name.as_str(), None)
         } else {
             None
         // Then check global macros.
@@ -1022,7 +1024,7 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
                                                   .filter_map(|(name, binding)| {
                 if binding.macro_kind() == Some(kind) { Some(name) } else { None }
             });
-            find_best_match_for_name(names, name, None)
+            find_best_match_for_name(names, &name.as_str(), None)
         // Then check modules.
         }).or_else(|| {
             let is_macro = |res| {
@@ -1032,7 +1034,7 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
                     false
                 }
             };
-            let ident = Ident::new(Symbol::intern(name), span);
+            let ident = Ident::new(name, span);
             self.lookup_typo_candidate(&[Segment::from_ident(ident)], MacroNS, is_macro, span)
                 .map(|suggestion| suggestion.candidate)
         });
@@ -1091,7 +1093,7 @@ pub fn define_macro(&mut self,
                         current_legacy_scope: &mut LegacyScope<'a>) {
         self.local_macro_def_scopes.insert(item.id, self.current_module);
         let ident = item.ident;
-        if ident.name == "macro_rules" {
+        if ident.name == sym::macro_rules {
             self.session.span_err(item.span, "user-defined macros may not be named `macro_rules`");
         }
 
@@ -1106,7 +1108,7 @@ pub fn define_macro(&mut self,
             let ident = ident.modern();
             self.macro_names.insert(ident);
             let res = Res::Def(DefKind::Macro(MacroKind::Bang), def_id);
-            let is_macro_export = attr::contains_name(&item.attrs, "macro_export");
+            let is_macro_export = attr::contains_name(&item.attrs, sym::macro_export);
             let vis = if is_macro_export {
                 ty::Visibility::Public
             } else {
@@ -1124,7 +1126,7 @@ pub fn define_macro(&mut self,
                 self.define(module, ident, MacroNS,
                             (res, vis, item.span, expansion, IsMacroExport));
             } else {
-                if !attr::contains_name(&item.attrs, "rustc_doc_only_macro") {
+                if !attr::contains_name(&item.attrs, sym::rustc_doc_only_macro) {
                     self.check_reserved_macro_name(ident, MacroNS);
                 }
                 self.unused_macros.insert(def_id);
index 9e6b8d035458de88d7e3ac31d6c0c4a230400251..4058f0bce0f9544e1eceb207a647b102a080d932 100644 (file)
@@ -29,7 +29,7 @@
 use syntax::ast::{self, Ident, Name, NodeId, CRATE_NODE_ID};
 use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
 use syntax::ext::hygiene::Mark;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax::{struct_span_err, unwrap_or};
 use syntax_pos::{MultiSpan, Span};
@@ -496,7 +496,8 @@ pub fn add_import_directive(&mut self,
         // Reserve some names that are not quite covered by the general check
         // performed on `Resolver::builtin_attrs`.
         if ns == MacroNS &&
-           (ident.name == "cfg" || ident.name == "cfg_attr" || ident.name == "derive") {
+           (ident.name == sym::cfg || ident.name == sym::cfg_attr ||
+            ident.name == sym::derive) {
             self.session.span_err(ident.span,
                                   &format!("name `{}` is reserved in macro namespace", ident));
         }
@@ -706,7 +707,7 @@ pub fn finalize_imports(&mut self) {
                 has_errors = true;
 
                 if let SingleImport { source, ref source_bindings, .. } = import.subclass {
-                    if source.name == "self" {
+                    if source.name == keywords::SelfLower.name() {
                         // Silence `unresolved import` error if E0429 is already emitted
                         if let Err(Determined) = source_bindings.value_ns.get() {
                             continue;
@@ -1041,7 +1042,8 @@ fn finalize_import(
                     let initial_res = source_bindings[ns].get().map(|initial_binding| {
                         all_ns_err = false;
                         if let Some(target_binding) = target_bindings[ns].get() {
-                            if target.name == "_" &&
+                            // Note that as_str() de-gensyms the Symbol
+                            if target.name.as_str() == "_" &&
                                initial_binding.is_extern_crate() && !initial_binding.is_import() {
                                 this.record_use(ident, ns, target_binding,
                                                 directive.module_path.is_empty());
@@ -1392,7 +1394,8 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
             // (e.g. implicitly injected `std`) cannot be properly encoded in metadata,
             // so they can cause name conflict errors downstream.
             let is_good_import = binding.is_import() && !binding.is_ambiguity() &&
-                                 !(ident.name.is_gensymed() && ident.name != "_");
+                                 // Note that as_str() de-gensyms the Symbol
+                                 !(ident.name.is_gensymed() && ident.name.as_str() != "_");
             if is_good_import || binding.is_macro_def() {
                 let res = binding.res();
                 if res != Res::Err {
index a45e32ddb6690ccbd0863b9fd14f0bd0638e081a..1e65f868ebac0bea2b75f4c301105c5a9cd0e0fa 100644 (file)
@@ -463,10 +463,12 @@ fn process_assoc_const(
         }
 
         // walk type and init value
-        self.visit_ty(typ);
-        if let Some(expr) = expr {
-            self.visit_expr(expr);
-        }
+        self.nest_tables(id, |v| {
+            v.visit_ty(typ);
+            if let Some(expr) = expr {
+                v.visit_expr(expr);
+            }
+        });
     }
 
     // FIXME tuple structs should generate tuple-specific data.
index f3e0fb32ec2dc28777ad61c03e79a3938fa8e700..e03da2ed608be02f02d3137dd1d9af17412ac6bb 100644 (file)
@@ -879,7 +879,7 @@ fn docs_for_attrs(&self, attrs: &[Attribute]) -> String {
         let mut result = String::new();
 
         for attr in attrs {
-            if attr.check_name("doc") {
+            if attr.check_name(sym::doc) {
                 if let Some(val) = attr.value_str() {
                     if attr.is_sugared_doc {
                         result.push_str(&strip_doc_comment_decoration(&val.as_str()));
@@ -889,10 +889,10 @@ fn docs_for_attrs(&self, attrs: &[Attribute]) -> String {
                     result.push('\n');
                 } else if let Some(meta_list) = attr.meta_item_list() {
                     meta_list.into_iter()
-                             .filter(|it| it.check_name("include"))
+                             .filter(|it| it.check_name(sym::include))
                              .filter_map(|it| it.meta_item_list().map(|l| l.to_owned()))
                              .flat_map(|it| it)
-                             .filter(|meta| meta.check_name("contents"))
+                             .filter(|meta| meta.check_name(sym::contents))
                              .filter_map(|meta| meta.value_str())
                              .for_each(|val| {
                                  result.push_str(&val.as_str());
@@ -1197,7 +1197,7 @@ fn null_id() -> rls_data::Id {
 fn lower_attributes(attrs: Vec<Attribute>, scx: &SaveContext<'_, '_>) -> Vec<rls_data::Attribute> {
     attrs.into_iter()
     // Only retain real attributes. Doc comments are lowered separately.
-    .filter(|attr| attr.path != "doc")
+    .filter(|attr| attr.path != sym::doc)
     .map(|mut attr| {
         // Remove the surrounding '#[..]' or '#![..]' of the pretty printed
         // attribute. First normalize all inner attribute (#![..]) to outer
index 9dd343b6c8de8ee1ee964858f63dfb6cb7a9b7e4..53364e72bfe3ad70e71e49efe893799c8d4ed8b5 100644 (file)
@@ -14,7 +14,7 @@ pub fn opts() -> TargetOptions {
     //
     // Here we detect what version is being requested, defaulting to 10.7. ELF
     // TLS is flagged as enabled if it looks to be supported.
-    let version = macos_deployment_target().unwrap_or((10, 7));
+    let version = macos_deployment_target();
 
     TargetOptions {
         // macOS has -dead_strip, which doesn't rely on function_sections
@@ -35,7 +35,7 @@ pub fn opts() -> TargetOptions {
     }
 }
 
-fn macos_deployment_target() -> Option<(u32, u32)> {
+fn macos_deployment_target() -> (u32, u32) {
     let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok();
     let version = deployment_target.as_ref().and_then(|s| {
         let mut i = s.splitn(2, '.');
@@ -44,17 +44,10 @@ fn macos_deployment_target() -> Option<(u32, u32)> {
         a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok()
     });
 
-    version
+    version.unwrap_or((10, 7))
 }
 
 pub fn macos_llvm_target(arch: &str) -> String {
-    let version = macos_deployment_target();
-    let llvm_target = match version {
-        Some((major, minor)) => {
-            format!("{}-apple-macosx{}.{}.0", arch, major, minor)
-        },
-        None => format!("{}-apple-darwin", arch)
-    };
-
-    llvm_target
+    let (major, minor) = macos_deployment_target();
+    format!("{}-apple-macosx{}.{}.0", arch, major, minor)
 }
diff --git a/src/librustc_target/spec/bitrig_base.rs b/src/librustc_target/spec/bitrig_base.rs
deleted file mode 100644 (file)
index 9b34119..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-use crate::spec::{TargetOptions, RelroLevel};
-use std::default::Default;
-
-pub fn opts() -> TargetOptions {
-    TargetOptions {
-        dynamic_linking: true,
-        executables: true,
-        target_family: Some("unix".to_string()),
-        linker_is_gnu: true,
-        has_rpath: true,
-        position_independent_executables: true,
-        relro_level: RelroLevel::Full,
-
-        .. Default::default()
-    }
-}
index b30a4fe76a2da848ba48cf90493eab686fbad1e4..844edbb946a515f9899974e64ee1acecc79ef50d 100644 (file)
@@ -47,7 +47,6 @@
 mod apple_base;
 mod apple_ios_base;
 mod arm_base;
-mod bitrig_base;
 mod cloudabi_base;
 mod dragonfly_base;
 mod freebsd_base;
@@ -390,8 +389,6 @@ fn $module() {
     ("i686-unknown-dragonfly", i686_unknown_dragonfly),
     ("x86_64-unknown-dragonfly", x86_64_unknown_dragonfly),
 
-    ("x86_64-unknown-bitrig", x86_64_unknown_bitrig),
-
     ("aarch64-unknown-openbsd", aarch64_unknown_openbsd),
     ("i686-unknown-openbsd", i686_unknown_openbsd),
     ("x86_64-unknown-openbsd", x86_64_unknown_openbsd),
diff --git a/src/librustc_target/spec/x86_64_unknown_bitrig.rs b/src/librustc_target/spec/x86_64_unknown_bitrig.rs
deleted file mode 100644 (file)
index 999d93a..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-use crate::spec::{LinkerFlavor, Target, TargetResult};
-
-pub fn target() -> TargetResult {
-    let mut base = super::bitrig_base::opts();
-    base.cpu = "x86-64".to_string();
-    base.max_atomic_width = Some(64);
-    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
-    base.stack_probes = true;
-
-    Ok(Target {
-        llvm_target: "x86_64-unknown-bitrig".to_string(),
-        target_endian: "little".to_string(),
-        target_pointer_width: "64".to_string(),
-        target_c_int_width: "32".to_string(),
-        data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
-        arch: "x86_64".to_string(),
-        target_os: "bitrig".to_string(),
-        target_env: String::new(),
-        target_vendor: "unknown".to_string(),
-        linker_flavor: LinkerFlavor::Gcc,
-        options: base,
-    })
-}
index 50c2130263295dba85129f6d45f3757da162349c..580b1571e52bb1dd55bc5254ecf05e87806b9e20 100644 (file)
@@ -21,6 +21,7 @@
 use rustc::ty::{self, List, TyCtxt};
 use rustc::ty::subst::{Subst, InternalSubsts};
 use syntax::ast;
+use syntax::symbol::sym;
 
 use std::iter;
 
@@ -640,11 +641,11 @@ fn process_attrs(&mut self, hir_id: hir::HirId, attrs: &[ast::Attribute]) {
         for attr in attrs {
             let mut clauses = None;
 
-            if attr.check_name("rustc_dump_program_clauses") {
+            if attr.check_name(sym::rustc_dump_program_clauses) {
                 clauses = Some(self.tcx.program_clauses_for(def_id));
             }
 
-            if attr.check_name("rustc_dump_env_program_clauses") {
+            if attr.check_name(sym::rustc_dump_env_program_clauses) {
                 let environment = self.tcx.environment(def_id);
                 clauses = Some(self.tcx.program_clauses_for_env(environment));
             }
index da47ccf38a0263416dba53b6d62585b2d90a1955..caefe1242115508ddec3ef0c70499a83e6f1ea3e 100644 (file)
@@ -25,6 +25,7 @@
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::ptr::P;
 use syntax::util::lev_distance::find_best_match_for_name;
+use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, Span, MultiSpan};
 use crate::util::common::ErrorReported;
 use crate::util::nodemap::FxHashMap;
@@ -802,7 +803,7 @@ fn create_substs_for_ast_trait_ref(
             } else {
                 "parenthetical notation is only stable when used with `Fn`-family traits"
             };
-            emit_feature_err(&self.tcx().sess.parse_sess, "unboxed_closures",
+            emit_feature_err(&self.tcx().sess.parse_sess, sym::unboxed_closures,
                              span, GateIssue::Language, msg);
         }
 
index 008975068e581a374daca5a7eff7d34cc4e046ab..90b2643d165bea7f2ab6e23cfacbb56ae5a53a85 100644 (file)
@@ -68,6 +68,7 @@
 use std::ops::Deref;
 use syntax::feature_gate;
 use syntax::ptr::P;
+use syntax::symbol::sym;
 use syntax_pos;
 
 struct Coerce<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
@@ -620,7 +621,7 @@ fn coerce_unsized(&self, source: Ty<'tcx>, target: Ty<'tcx>) -> CoerceResult<'tc
 
         if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion {
             feature_gate::emit_feature_err(&self.tcx.sess.parse_sess,
-                                           "unsized_tuple_coercion",
+                                           sym::unsized_tuple_coercion,
                                            self.cause.span,
                                            feature_gate::GateIssue::Language,
                                            feature_gate::EXPLAIN_UNSIZED_TUPLE_COERCION);
index 1699447886aef89a30cb792f5b9e77baad017e3d..8d68179b495c6015738344919f05b2af1a07daca 100644 (file)
@@ -2,6 +2,7 @@
 use rustc::infer::InferOk;
 use rustc::traits::{self, ObligationCause, ObligationCauseCode};
 
+use syntax::symbol::sym;
 use syntax::util::parser::PREC_POSTFIX;
 use syntax_pos::Span;
 use rustc::hir;
@@ -197,7 +198,7 @@ pub fn get_conversion_methods(&self, span: Span, expected: Ty<'tcx>, checked_ty:
                 //
                 // FIXME? Other potential candidate methods: `as_ref` and
                 // `as_mut`?
-                .find(|a| a.check_name("rustc_conversion_suggestion")).is_some()
+                .find(|a| a.check_name(sym::rustc_conversion_suggestion)).is_some()
         });
 
         methods
index a32745f27e1a09c59a57d1794e773bd8f98c33fa..362b6f0504d99aed306f7bba354acad944a04182 100644 (file)
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::ptr::P;
 use syntax::source_map::{DUMMY_SP, original_sp};
-use syntax::symbol::{Symbol, LocalInternedString, keywords};
+use syntax::symbol::{Symbol, LocalInternedString, keywords, sym};
 use syntax::util::lev_distance::find_best_match_for_name;
 
 use std::cell::{Cell, RefCell, Ref, RefMut};
@@ -1840,7 +1840,7 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     if vs.is_empty() {
         let attributes = tcx.get_attrs(def_id);
-        if let Some(attr) = attr::find_by_name(&attributes, "repr") {
+        if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
             struct_span_err!(
                 tcx.sess, attr.span, E0084,
                 "unsupported representation for zero-variant enum")
@@ -1853,7 +1853,7 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
         if !tcx.features().repr128 {
             emit_feature_err(&tcx.sess.parse_sess,
-                             "repr128",
+                             sym::repr128,
                              sp,
                              GateIssue::Language,
                              "repr with 128-bit type is unstable");
@@ -3083,7 +3083,7 @@ fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
 
     // AST fragment checking
     fn check_lit(&self,
-                 lit: &ast::Lit,
+                 lit: &hir::Lit,
                  expected: Expectation<'tcx>)
                  -> Ty<'tcx>
     {
@@ -4197,7 +4197,8 @@ fn check_expr_kind(
                         // ... except when we try to 'break rust;'.
                         // ICE this expression in particular (see #43162).
                         if let ExprKind::Path(QPath::Resolved(_, ref path)) = e.node {
-                            if path.segments.len() == 1 && path.segments[0].ident.name == "rust" {
+                            if path.segments.len() == 1 &&
+                               path.segments[0].ident.name == sym::rust {
                                 fatally_break_rust(self.tcx.sess);
                             }
                         }
@@ -5499,7 +5500,7 @@ fn check_rustc_args_require_const(&self,
                                       span: Span) {
         // We're only interested in functions tagged with
         // #[rustc_args_required_const], so ignore anything that's not.
-        if !self.tcx.has_attr(def_id, "rustc_args_required_const") {
+        if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
             return
         }
 
index fd7d6fe694ccd747ca08de924ecab3e8a37b928a..b009c8ea6dce17a3d28b22da83ac9f2eb1fab053 100644 (file)
@@ -13,6 +13,7 @@
 use syntax::ast;
 use syntax::feature_gate::{self, GateIssue};
 use syntax_pos::Span;
+use syntax::symbol::sym;
 use errors::{DiagnosticBuilder, DiagnosticId};
 
 use rustc::hir::itemlikevisit::ParItemLikeVisitor;
@@ -796,7 +797,7 @@ fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
                 // report error, would have worked with arbitrary_self_types
                 feature_gate::feature_err(
                     &fcx.tcx.sess.parse_sess,
-                    "arbitrary_self_types",
+                    sym::arbitrary_self_types,
                     span,
                     GateIssue::Language,
                     &format!(
index bf978352faee93b10d07a6bac1eb112377c42220..13baf667808f817293c72f6f13ed44dac147ae29 100644 (file)
@@ -16,6 +16,7 @@
 use rustc::util::nodemap::DefIdSet;
 use rustc_data_structures::sync::Lrc;
 use std::mem;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 ///////////////////////////////////////////////////////////////////////////
@@ -36,8 +37,8 @@ pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body) -> &'gcx ty::Type
         let item_def_id = self.tcx.hir().local_def_id(item_id);
 
         // This attribute causes us to dump some writeback information
-        // in the form of errors, which is used for unit tests.
-        let rustc_dump_user_substs = self.tcx.has_attr(item_def_id, "rustc_dump_user_substs");
+        // in the form of errors, which is uSymbolfor unit tests.
+        let rustc_dump_user_substs = self.tcx.has_attr(item_def_id, sym::rustc_dump_user_substs);
 
         let mut wbcx = WritebackCx::new(self, body, rustc_dump_user_substs);
         for arg in &body.arguments {
@@ -465,6 +466,8 @@ fn visit_opaque_types(&mut self, span: Span) {
             let hir_id = self.tcx().hir().as_local_hir_id(def_id).unwrap();
             let instantiated_ty = self.resolve(&opaque_defn.concrete_ty, &hir_id);
 
+            debug_assert!(!instantiated_ty.has_escaping_bound_vars());
+
             let generics = self.tcx().generics_of(def_id);
 
             let definition_ty = if generics.parent.is_some() {
@@ -523,8 +526,9 @@ fn visit_opaque_types(&mut self, span: Span) {
                     },
                     lt_op: |region| {
                         match region {
-                            // ignore static regions
-                            ty::ReStatic => region,
+                            // Skip static and bound regions: they don't
+                            // require substitution.
+                            ty::ReStatic | ty::ReLateBound(..) => region,
                             _ => {
                                 trace!("checking {:?}", region);
                                 for (subst, p) in opaque_defn.substs.iter().zip(&generics.params) {
index 4185999fdd6d734e8c9acae0ff4d1df9dbb4826d..6527e8655b5ef21bb6d93a7b65f5fed7c8c098fa 100644 (file)
@@ -39,7 +39,7 @@
 use syntax::attr::{InlineAttr, OptimizeAttr, list_contains_name, mark_used};
 use syntax::source_map::Spanned;
 use syntax::feature_gate;
-use syntax::symbol::{keywords, Symbol};
+use syntax::symbol::{keywords, Symbol, sym};
 use syntax_pos::{Span, DUMMY_SP};
 
 use rustc::hir::def::{CtorKind, Res, DefKind};
@@ -750,7 +750,7 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::
         _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
     };
 
-    let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
+    let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar);
     if paren_sugar && !tcx.features().unboxed_closures {
         let mut err = tcx.sess.struct_span_err(
             item.span,
@@ -765,7 +765,7 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::
         err.emit();
     }
 
-    let is_marker = tcx.has_attr(def_id, "marker");
+    let is_marker = tcx.has_attr(def_id, sym::marker);
     let def_path_hash = tcx.def_path_hash(def_id);
     let def = ty::TraitDef::new(def_id, unsafety, paren_sugar, is_auto, is_marker, def_path_hash);
     tcx.alloc_trait_def(def)
@@ -1404,7 +1404,13 @@ pub fn checked_type_of<'a, 'tcx>(
                                     if !fail {
                                         return None;
                                     }
-                                    bug!("unexpected const parent path def {:?}", x);
+                                    tcx.sess.delay_span_bug(
+                                        DUMMY_SP,
+                                        &format!(
+                                            "unexpected const parent path def {:?}", x
+                                        ),
+                                    );
+                                    tcx.types.err
                                 }
                             }
                         }
@@ -1412,7 +1418,13 @@ pub fn checked_type_of<'a, 'tcx>(
                             if !fail {
                                 return None;
                             }
-                            bug!("unexpected const parent path {:?}", x);
+                            tcx.sess.delay_span_bug(
+                                DUMMY_SP,
+                                &format!(
+                                    "unexpected const parent path {:?}", x
+                                ),
+                            );
+                            tcx.types.err
                         }
                     }
                 }
@@ -1421,7 +1433,13 @@ pub fn checked_type_of<'a, 'tcx>(
                     if !fail {
                         return None;
                     }
-                    bug!("unexpected const parent in type_of_def_id(): {:?}", x);
+                    tcx.sess.delay_span_bug(
+                        DUMMY_SP,
+                        &format!(
+                            "unexpected const parent in type_of_def_id(): {:?}", x
+                        ),
+                    );
+                    tcx.types.err
                 }
             }
         }
@@ -2382,7 +2400,7 @@ fn from_target_feature(
     tcx: TyCtxt<'_, '_, '_>,
     id: DefId,
     attr: &ast::Attribute,
-    whitelist: &FxHashMap<String, Option<String>>,
+    whitelist: &FxHashMap<String, Option<Symbol>>,
     target_features: &mut Vec<Symbol>,
 ) {
     let list = match attr.meta_item_list() {
@@ -2392,7 +2410,7 @@ fn from_target_feature(
     let rust_features = tcx.features();
     for item in list {
         // Only `enable = ...` is accepted in the meta item list
-        if !item.check_name("enable") {
+        if !item.check_name(sym::enable) {
             let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
                        currently";
             tcx.sess.span_err(item.span(), &msg);
@@ -2435,29 +2453,29 @@ fn from_target_feature(
             };
 
             // Only allow features whose feature gates have been enabled
-            let allowed = match feature_gate.as_ref().map(|s| &**s) {
-                Some("arm_target_feature") => rust_features.arm_target_feature,
-                Some("aarch64_target_feature") => rust_features.aarch64_target_feature,
-                Some("hexagon_target_feature") => rust_features.hexagon_target_feature,
-                Some("powerpc_target_feature") => rust_features.powerpc_target_feature,
-                Some("mips_target_feature") => rust_features.mips_target_feature,
-                Some("avx512_target_feature") => rust_features.avx512_target_feature,
-                Some("mmx_target_feature") => rust_features.mmx_target_feature,
-                Some("sse4a_target_feature") => rust_features.sse4a_target_feature,
-                Some("tbm_target_feature") => rust_features.tbm_target_feature,
-                Some("wasm_target_feature") => rust_features.wasm_target_feature,
-                Some("cmpxchg16b_target_feature") => rust_features.cmpxchg16b_target_feature,
-                Some("adx_target_feature") => rust_features.adx_target_feature,
-                Some("movbe_target_feature") => rust_features.movbe_target_feature,
-                Some("rtm_target_feature") => rust_features.rtm_target_feature,
-                Some("f16c_target_feature") => rust_features.f16c_target_feature,
+            let allowed = match feature_gate.as_ref().map(|s| *s) {
+                Some(sym::arm_target_feature) => rust_features.arm_target_feature,
+                Some(sym::aarch64_target_feature) => rust_features.aarch64_target_feature,
+                Some(sym::hexagon_target_feature) => rust_features.hexagon_target_feature,
+                Some(sym::powerpc_target_feature) => rust_features.powerpc_target_feature,
+                Some(sym::mips_target_feature) => rust_features.mips_target_feature,
+                Some(sym::avx512_target_feature) => rust_features.avx512_target_feature,
+                Some(sym::mmx_target_feature) => rust_features.mmx_target_feature,
+                Some(sym::sse4a_target_feature) => rust_features.sse4a_target_feature,
+                Some(sym::tbm_target_feature) => rust_features.tbm_target_feature,
+                Some(sym::wasm_target_feature) => rust_features.wasm_target_feature,
+                Some(sym::cmpxchg16b_target_feature) => rust_features.cmpxchg16b_target_feature,
+                Some(sym::adx_target_feature) => rust_features.adx_target_feature,
+                Some(sym::movbe_target_feature) => rust_features.movbe_target_feature,
+                Some(sym::rtm_target_feature) => rust_features.rtm_target_feature,
+                Some(sym::f16c_target_feature) => rust_features.f16c_target_feature,
                 Some(name) => bug!("unknown target feature gate {}", name),
                 None => true,
             };
             if !allowed && id.is_local() {
                 feature_gate::emit_feature_err(
                     &tcx.sess.parse_sess,
-                    feature_gate.as_ref().unwrap(),
+                    feature_gate.unwrap(),
                     item.span(),
                     feature_gate::GateIssue::Language,
                     &format!("the target feature `{}` is currently unstable", feature),
@@ -2512,13 +2530,13 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
 
     let mut inline_span = None;
     for attr in attrs.iter() {
-        if attr.check_name("cold") {
+        if attr.check_name(sym::cold) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
-        } else if attr.check_name("allocator") {
+        } else if attr.check_name(sym::allocator) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR;
-        } else if attr.check_name("unwind") {
+        } else if attr.check_name(sym::unwind) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::UNWIND;
-        } else if attr.check_name("ffi_returns_twice") {
+        } else if attr.check_name(sym::ffi_returns_twice) {
             if tcx.is_foreign_item(id) {
                 codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_RETURNS_TWICE;
             } else {
@@ -2530,21 +2548,21 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                     "`#[ffi_returns_twice]` may only be used on foreign functions"
                 ).emit();
             }
-        } else if attr.check_name("rustc_allocator_nounwind") {
+        } else if attr.check_name(sym::rustc_allocator_nounwind) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND;
-        } else if attr.check_name("naked") {
+        } else if attr.check_name(sym::naked) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED;
-        } else if attr.check_name("no_mangle") {
+        } else if attr.check_name(sym::no_mangle) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
-        } else if attr.check_name("rustc_std_internal_symbol") {
+        } else if attr.check_name(sym::rustc_std_internal_symbol) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
-        } else if attr.check_name("no_debug") {
+        } else if attr.check_name(sym::no_debug) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_DEBUG;
-        } else if attr.check_name("used") {
+        } else if attr.check_name(sym::used) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
-        } else if attr.check_name("thread_local") {
+        } else if attr.check_name(sym::thread_local) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
-        } else if attr.check_name("export_name") {
+        } else if attr.check_name(sym::export_name) {
             if let Some(s) = attr.value_str() {
                 if s.as_str().contains("\0") {
                     // `#[export_name = ...]` will be converted to a null-terminated string,
@@ -2558,7 +2576,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                 }
                 codegen_fn_attrs.export_name = Some(s);
             }
-        } else if attr.check_name("target_feature") {
+        } else if attr.check_name(sym::target_feature) {
             if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
                 let msg = "#[target_feature(..)] can only be applied to \
                            `unsafe` function";
@@ -2571,11 +2589,11 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                 &whitelist,
                 &mut codegen_fn_attrs.target_features,
             );
-        } else if attr.check_name("linkage") {
+        } else if attr.check_name(sym::linkage) {
             if let Some(val) = attr.value_str() {
                 codegen_fn_attrs.linkage = Some(linkage_by_name(tcx, id, &val.as_str()));
             }
-        } else if attr.check_name("link_section") {
+        } else if attr.check_name(sym::link_section) {
             if let Some(val) = attr.value_str() {
                 if val.as_str().bytes().any(|b| b == 0) {
                     let msg = format!(
@@ -2588,13 +2606,13 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                     codegen_fn_attrs.link_section = Some(val);
                 }
             }
-        } else if attr.check_name("link_name") {
+        } else if attr.check_name(sym::link_name) {
             codegen_fn_attrs.link_name = attr.value_str();
         }
     }
 
     codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
-        if attr.path != "inline" {
+        if attr.path != sym::inline {
             return ia;
         }
         match attr.meta().map(|i| i.node) {
@@ -2613,9 +2631,9 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                         "expected one argument"
                     );
                     InlineAttr::None
-                } else if list_contains_name(&items[..], "always") {
+                } else if list_contains_name(&items[..], sym::always) {
                     InlineAttr::Always
-                } else if list_contains_name(&items[..], "never") {
+                } else if list_contains_name(&items[..], sym::never) {
                     InlineAttr::Never
                 } else {
                     span_err!(
@@ -2634,7 +2652,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
     });
 
     codegen_fn_attrs.optimize = attrs.iter().fold(OptimizeAttr::None, |ia, attr| {
-        if attr.path != "optimize" {
+        if attr.path != sym::optimize {
             return ia;
         }
         let err = |sp, s| span_err!(tcx.sess.diagnostic(), sp, E0722, "{}", s);
@@ -2649,9 +2667,9 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
                 if items.len() != 1 {
                     err(attr.span, "expected one argument");
                     OptimizeAttr::None
-                } else if list_contains_name(&items[..], "size") {
+                } else if list_contains_name(&items[..], sym::size) {
                     OptimizeAttr::Size
-                } else if list_contains_name(&items[..], "speed") {
+                } else if list_contains_name(&items[..], sym::speed) {
                     OptimizeAttr::Speed
                 } else {
                     err(items[0].span(), "invalid argument");
index e3e2fe7106a08560760f8aecb992078acfd75297..a6b5b99982ec6b5ba8a4cb72b36446268a17999c 100644 (file)
@@ -5,6 +5,7 @@
 use rustc::ty::subst::UnpackedKind;
 use rustc::ty::{self, CratePredicatesMap, TyCtxt};
 use rustc_data_structures::sync::Lrc;
+use syntax::symbol::sym;
 
 mod explicit;
 mod implicit_infer;
@@ -40,7 +41,7 @@ fn inferred_outlives_of<'a, 'tcx>(
                     .map(|p| *p)
                     .unwrap_or(&[]);
 
-                if tcx.has_attr(item_def_id, "rustc_outlives") {
+                if tcx.has_attr(item_def_id, sym::rustc_outlives) {
                     let mut pred: Vec<String> = predicates
                         .iter()
                         .map(|out_pred| match out_pred {
index e10c8361207186d15e32b4b7aaeee89a690fa840..54fd4fad1d1956c95284e8a2a5287f8c2c8008ac 100644 (file)
@@ -1,6 +1,7 @@
 use rustc::hir;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::ty::TyCtxt;
+use syntax::symbol::sym;
 
 pub fn test_inferred_outlives<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     tcx.hir()
@@ -18,7 +19,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
 
         // For unit testing: check for a special "rustc_outlives"
         // attribute and report an error with various results if found.
-        if self.tcx.has_attr(item_def_id, "rustc_outlives") {
+        if self.tcx.has_attr(item_def_id, sym::rustc_outlives) {
             let inferred_outlives_of = self.tcx.inferred_outlives_of(item_def_id);
             span_err!(
                 self.tcx.sess,
index d04b1b276a2cc9156a7a9583f76b2e266825e435..b5195826b8631a4a6278660107442ff309c14590 100644 (file)
@@ -1,6 +1,7 @@
 use rustc::hir;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::ty::TyCtxt;
+use syntax::symbol::sym;
 
 pub fn test_variance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     tcx.hir().krate().visit_all_item_likes(&mut VarianceTest { tcx });
@@ -16,7 +17,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
 
         // For unit testing: check for a special "rustc_variance"
         // attribute and report an error with various results if found.
-        if self.tcx.has_attr(item_def_id, "rustc_variance") {
+        if self.tcx.has_attr(item_def_id, sym::rustc_variance) {
             let variances_of = self.tcx.variances_of(item_def_id);
             span_err!(self.tcx.sess,
                       item.span,
index 69445451503cc7404d7b5b2c1325e30569cdfa15..61399e0568cb10bf2ca8406a7c1af04ca88c6854 100644 (file)
@@ -7,7 +7,7 @@
 use std::fmt::{self, Write};
 use std::ops;
 
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::ast::{MetaItem, MetaItemKind, NestedMetaItem, LitKind};
 use syntax::parse::ParseSess;
 use syntax::feature_gate::Features;
@@ -186,7 +186,7 @@ fn should_append_only_to_description(&self) -> bool {
 
     fn should_use_with_in_description(&self) -> bool {
         match *self {
-            Cfg::Cfg(ref name, _) if name == &"target_feature" => true,
+            Cfg::Cfg(name, _) if name == sym::target_feature => true,
             _ => false,
         }
     }
@@ -338,7 +338,6 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
                     ("debug_assertions", None) => "debug-assertions enabled",
                     ("target_os", Some(os)) => match &*os.as_str() {
                         "android" => "Android",
-                        "bitrig" => "Bitrig",
                         "dragonfly" => "DragonFly BSD",
                         "emscripten" => "Emscripten",
                         "freebsd" => "FreeBSD",
@@ -414,10 +413,11 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
 mod test {
     use super::Cfg;
 
-    use syntax::symbol::Symbol;
+    use syntax_pos::DUMMY_SP;
     use syntax::ast::*;
+    use syntax::attr;
     use syntax::source_map::dummy_spanned;
-    use syntax_pos::DUMMY_SP;
+    use syntax::symbol::Symbol;
     use syntax::with_globals;
 
     fn word_cfg(s: &str) -> Cfg {
@@ -592,14 +592,10 @@ fn test_parse_ok() {
             let mi = dummy_meta_item_word("all");
             assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all")));
 
-            let mi = MetaItem {
-                path: Path::from_ident(Ident::from_str("all")),
-                node: MetaItemKind::NameValue(dummy_spanned(LitKind::Str(
-                    Symbol::intern("done"),
-                    StrStyle::Cooked,
-                ))),
-                span: DUMMY_SP,
-            };
+            let mi = attr::mk_name_value_item_str(
+                Ident::from_str("all"),
+                dummy_spanned(Symbol::intern("done"))
+            );
             assert_eq!(Cfg::parse(&mi), Ok(name_value_cfg("all", "done")));
 
             let mi = dummy_meta_item_list!(all, [a, b]);
@@ -627,11 +623,12 @@ fn test_parse_ok() {
     #[test]
     fn test_parse_err() {
         with_globals(|| {
-            let mi = MetaItem {
-                path: Path::from_ident(Ident::from_str("foo")),
-                node: MetaItemKind::NameValue(dummy_spanned(LitKind::Bool(false))),
-                span: DUMMY_SP,
-            };
+            let mi = attr::mk_name_value_item(
+                DUMMY_SP,
+                Ident::from_str("foo"),
+                LitKind::Bool(false),
+                DUMMY_SP,
+            );
             assert!(Cfg::parse(&mi).is_err());
 
             let mi = dummy_meta_item_list!(not, [a, b]);
index d9d6b8e07e99482a5b8872290ff807ce3774c248..15108a7dbb91c392836ea59e926961ce55f79721 100644 (file)
@@ -4,6 +4,7 @@
 
 use syntax::ast;
 use syntax::ext::base::{MacroKind, SyntaxExtension};
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 use rustc::hir;
@@ -186,7 +187,7 @@ pub fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait {
     let generics = (cx.tcx.generics_of(did), &predicates).clean(cx);
     let generics = filter_non_trait_generics(did, generics);
     let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
-    let is_spotlight = load_attrs(cx, did).has_doc_flag("spotlight");
+    let is_spotlight = load_attrs(cx, did).has_doc_flag(sym::spotlight);
     let is_auto = cx.tcx.trait_is_auto(did);
     clean::Trait {
         auto: auto_trait,
index 3a260db806520a69261a447c7681225b0a001b9f..f9a43ccfbace182f71b5e5f9dd824338d17f986a 100644 (file)
@@ -32,6 +32,7 @@
 use syntax::source_map::{dummy_spanned, Spanned};
 use syntax::ptr::P;
 use syntax::symbol::keywords::{self, Keyword};
+use syntax::symbol::{Symbol, sym};
 use syntax::symbol::InternedString;
 use syntax_pos::{self, Pos, FileName};
 
@@ -170,7 +171,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Crate {
                     // `compiler_builtins` should be masked too, but we can't apply
                     // `#[doc(masked)]` to the injected `extern crate` because it's unstable.
                     if it.is_extern_crate()
-                        && (it.attrs.has_doc_flag("masked")
+                        && (it.attrs.has_doc_flag(sym::masked)
                             || self.cx.tcx.is_compiler_builtins(it.def_id.krate))
                     {
                         masked_crates.insert(it.def_id.krate);
@@ -261,9 +262,9 @@ fn clean(&self, cx: &DocContext<'_>) -> ExternalCrate {
             if let Res::Def(DefKind::Mod, def_id) = res {
                 let attrs = cx.tcx.get_attrs(def_id).clean(cx);
                 let mut prim = None;
-                for attr in attrs.lists("doc") {
+                for attr in attrs.lists(sym::doc) {
                     if let Some(v) = attr.value_str() {
-                        if attr.check_name("primitive") {
+                        if attr.check_name(sym::primitive) {
                             prim = PrimitiveType::from_str(&v.as_str());
                             if prim.is_some() {
                                 break;
@@ -305,9 +306,9 @@ fn clean(&self, cx: &DocContext<'_>) -> ExternalCrate {
             if let Res::Def(DefKind::Mod, def_id) = res {
                 let attrs = cx.tcx.get_attrs(def_id).clean(cx);
                 let mut keyword = None;
-                for attr in attrs.lists("doc") {
+                for attr in attrs.lists(sym::doc) {
                     if let Some(v) = attr.value_str() {
-                        if attr.check_name("keyword") {
+                        if attr.check_name(sym::keyword) {
                             keyword = Keyword::from_str(&v.as_str()).ok()
                                                                     .map(|x| x.name().to_string());
                             if keyword.is_some() {
@@ -501,7 +502,7 @@ pub fn stable_since(&self) -> Option<&str> {
 
     pub fn is_non_exhaustive(&self) -> bool {
         self.attrs.other_attrs.iter()
-            .any(|a| a.check_name("non_exhaustive"))
+            .any(|a| a.check_name(sym::non_exhaustive))
     }
 
     /// Returns a documentation-level item type from the item.
@@ -669,7 +670,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
 pub struct ListAttributesIter<'a> {
     attrs: slice::Iter<'a, ast::Attribute>,
     current_list: vec::IntoIter<ast::NestedMetaItem>,
-    name: &'a str
+    name: Symbol,
 }
 
 impl<'a> Iterator for ListAttributesIter<'a> {
@@ -702,11 +703,11 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 
 pub trait AttributesExt {
     /// Finds an attribute as List and returns the list of attributes nested inside.
-    fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a>;
+    fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a>;
 }
 
 impl AttributesExt for [ast::Attribute] {
-    fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a> {
+    fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> {
         ListAttributesIter {
             attrs: self.iter(),
             current_list: Vec::new().into_iter(),
@@ -717,11 +718,11 @@ fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a> {
 
 pub trait NestedAttributesExt {
     /// Returns `true` if the attribute list contains a specific `Word`
-    fn has_word(self, word: &str) -> bool;
+    fn has_word(self, word: Symbol) -> bool;
 }
 
 impl<I: IntoIterator<Item=ast::NestedMetaItem>> NestedAttributesExt for I {
-    fn has_word(self, word: &str) -> bool {
+    fn has_word(self, word: Symbol) -> bool {
         self.into_iter().any(|attr| attr.is_word() && attr.check_name(word))
     }
 }
@@ -803,7 +804,7 @@ fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
         if let ast::MetaItemKind::List(ref nmis) = mi.node {
             if nmis.len() == 1 {
                 if let MetaItem(ref cfg_mi) = nmis[0] {
-                    if cfg_mi.check_name("cfg") {
+                    if cfg_mi.check_name(sym::cfg) {
                         if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.node {
                             if cfg_nmis.len() == 1 {
                                 if let MetaItem(ref content_mi) = cfg_nmis[0] {
@@ -827,7 +828,7 @@ fn extract_include(mi: &ast::MetaItem)
     {
         mi.meta_item_list().and_then(|list| {
             for meta in list {
-                if meta.check_name("include") {
+                if meta.check_name(sym::include) {
                     // the actual compiled `#[doc(include="filename")]` gets expanded to
                     // `#[doc(include(file="filename", contents="file contents")]` so we need to
                     // look for that instead
@@ -836,11 +837,11 @@ fn extract_include(mi: &ast::MetaItem)
                         let mut contents: Option<String> = None;
 
                         for it in list {
-                            if it.check_name("file") {
+                            if it.check_name(sym::file) {
                                 if let Some(name) = it.value_str() {
                                     filename = Some(name.to_string());
                                 }
-                            } else if it.check_name("contents") {
+                            } else if it.check_name(sym::contents) {
                                 if let Some(docs) = it.value_str() {
                                     contents = Some(docs.to_string());
                                 }
@@ -860,9 +861,9 @@ fn extract_include(mi: &ast::MetaItem)
         })
     }
 
-    pub fn has_doc_flag(&self, flag: &str) -> bool {
+    pub fn has_doc_flag(&self, flag: Symbol) -> bool {
         for attr in &self.other_attrs {
-            if !attr.check_name("doc") { continue; }
+            if !attr.check_name(sym::doc) { continue; }
 
             if let Some(items) = attr.meta_item_list() {
                 if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name(flag)) {
@@ -883,7 +884,7 @@ pub fn from_ast(diagnostic: &::errors::Handler,
 
         let other_attrs = attrs.iter().filter_map(|attr| {
             attr.with_desugared_doc(|attr| {
-                if attr.check_name("doc") {
+                if attr.check_name(sym::doc) {
                     if let Some(mi) = attr.meta() {
                         if let Some(value) = mi.value_str() {
                             // Extracted #[doc = "..."]
@@ -925,8 +926,8 @@ pub fn from_ast(diagnostic: &::errors::Handler,
 
         // treat #[target_feature(enable = "feat")] attributes as if they were
         // #[doc(cfg(target_feature = "feat"))] attributes as well
-        for attr in attrs.lists("target_feature") {
-            if attr.check_name("enable") {
+        for attr in attrs.lists(sym::target_feature) {
+            if attr.check_name(sym::enable) {
                 if let Some(feat) = attr.value_str() {
                     let meta = attr::mk_name_value_item_str(Ident::from_str("target_feature"),
                                                             dummy_spanned(feat));
@@ -938,7 +939,7 @@ pub fn from_ast(diagnostic: &::errors::Handler,
         }
 
         let inner_docs = attrs.iter()
-                              .filter(|a| a.check_name("doc"))
+                              .filter(|a| a.check_name(sym::doc))
                               .next()
                               .map_or(true, |a| a.style == AttrStyle::Inner);
 
@@ -1039,7 +1040,7 @@ fn hash<H: Hasher>(&self, hasher: &mut H) {
 }
 
 impl AttributesExt for Attributes {
-    fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a> {
+    fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> {
         self.other_attrs.lists(name)
     }
 }
@@ -2133,7 +2134,7 @@ pub struct Trait {
 impl Clean<Item> for doctree::Trait {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         let attrs = self.attrs.clean(cx);
-        let is_spotlight = attrs.has_doc_flag("spotlight");
+        let is_spotlight = attrs.has_doc_flag(sym::spotlight);
         Item {
             name: Some(self.name.clean(cx)),
             attrs: attrs,
@@ -3893,8 +3894,8 @@ impl Clean<Vec<Item>> for doctree::ExternCrate {
     fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
 
         let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| {
-            a.check_name("doc") && match a.meta_item_list() {
-                Some(l) => attr::list_contains_name(&l, "inline"),
+            a.check_name(sym::doc) && match a.meta_item_list() {
+                Some(l) => attr::list_contains_name(&l, sym::inline),
                 None => false,
             }
         });
@@ -3935,15 +3936,15 @@ fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
         // #[doc(no_inline)] attribute is present.
         // Don't inline doc(hidden) imports so they can be stripped at a later stage.
         let mut denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| {
-            a.check_name("doc") && match a.meta_item_list() {
-                Some(l) => attr::list_contains_name(&l, "no_inline") ||
-                           attr::list_contains_name(&l, "hidden"),
+            a.check_name(sym::doc) && match a.meta_item_list() {
+                Some(l) => attr::list_contains_name(&l, sym::no_inline) ||
+                           attr::list_contains_name(&l, sym::hidden),
                 None => false,
             }
         });
         // Also check whether imports were asked to be inlined, in case we're trying to re-export a
         // crate in Rust 2018+
-        let please_inline = self.attrs.lists("doc").has_word("inline");
+        let please_inline = self.attrs.lists(sym::doc).has_word(sym::inline);
         let path = self.path.clean(cx);
         let inner = if self.glob {
             if !denied {
@@ -4382,7 +4383,7 @@ pub fn enter_impl_trait<F, R>(cx: &DocContext<'_>, f: F) -> R
 
 // Start of code copied from rust-clippy
 
-pub fn path_to_def_local(tcx: TyCtxt<'_, '_, '_>, path: &[&str]) -> Option<DefId> {
+pub fn path_to_def_local(tcx: TyCtxt<'_, '_, '_>, path: &[Symbol]) -> Option<DefId> {
     let krate = tcx.hir().krate();
     let mut items = krate.module.item_ids.clone();
     let mut path_it = path.iter().peekable();
@@ -4407,7 +4408,7 @@ pub fn path_to_def_local(tcx: TyCtxt<'_, '_, '_>, path: &[&str]) -> Option<DefId
     }
 }
 
-pub fn path_to_def(tcx: TyCtxt<'_, '_, '_>, path: &[&str]) -> Option<DefId> {
+pub fn path_to_def(tcx: TyCtxt<'_, '_, '_>, path: &[Symbol]) -> Option<DefId> {
     let crates = tcx.crates();
 
     let krate = crates
index e91e3a029dacfe993d8af336c560bf271c1f2128..428f4f328b907987356c418a09511b582e205c3b 100644 (file)
@@ -18,6 +18,7 @@
 use syntax::source_map;
 use syntax::feature_gate::UnstableFeatures;
 use syntax::json::JsonEmitter;
+use syntax::symbol::sym;
 use errors;
 use errors::emitter::{Emitter, EmitterWriter};
 use parking_lot::ReentrantMutex;
@@ -367,9 +368,9 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
             };
 
             let send_trait = if crate_name == Some("core".to_string()) {
-                clean::path_to_def_local(tcx, &["marker", "Send"])
+                clean::path_to_def_local(tcx, &[sym::marker, sym::Send])
             } else {
-                clean::path_to_def(tcx, &["core", "marker", "Send"])
+                clean::path_to_def(tcx, &[sym::core, sym::marker, sym::Send])
             };
 
             let mut renderinfo = RenderInfo::default();
@@ -415,24 +416,24 @@ fn report_deprecated_attr(name: &str, diag: &errors::Handler) {
 
             // Process all of the crate attributes, extracting plugin metadata along
             // with the passes which we are supposed to run.
-            for attr in krate.module.as_ref().unwrap().attrs.lists("doc") {
+            for attr in krate.module.as_ref().unwrap().attrs.lists(sym::doc) {
                 let diag = ctxt.sess().diagnostic();
 
                 let name = attr.name_or_empty();
                 if attr.is_word() {
-                    if name == "no_default_passes" {
+                    if name == sym::no_default_passes {
                         report_deprecated_attr("no_default_passes", diag);
                         if default_passes == passes::DefaultPassOption::Default {
                             default_passes = passes::DefaultPassOption::None;
                         }
                     }
                 } else if let Some(value) = attr.value_str() {
-                    let sink = match name.get() {
-                        "passes" => {
+                    let sink = match name {
+                        sym::passes => {
                             report_deprecated_attr("passes = \"...\"", diag);
                             &mut manual_passes
                         },
-                        "plugins" => {
+                        sym::plugins => {
                             report_deprecated_attr("plugins = \"...\"", diag);
                             eprintln!("WARNING: #![doc(plugins = \"...\")] no longer functions; \
                                       see CVE-2018-1000622");
@@ -445,7 +446,7 @@ fn report_deprecated_attr(name: &str, diag: &errors::Handler) {
                     }
                 }
 
-                if attr.is_word() && name == "document_private_items" {
+                if attr.is_word() && name == sym::document_private_items {
                     if default_passes == passes::DefaultPassOption::Default {
                         default_passes = passes::DefaultPassOption::Private;
                     }
index d66455f91ba1a2e3e127ebb4d39d0b458110f41b..5bb06516ac49e81ebaf917d4ea9b9dcb8fd6a407 100644 (file)
@@ -318,6 +318,8 @@ fn write_token<W: Writer>(&mut self,
 
                     // Number literals.
                     token::Integer(..) | token::Float(..) => Class::Number,
+
+                    token::Bool(..) => panic!("literal token contains `Lit::Bool`"),
                 }
             }
 
index 472192a6464921a69b5da6e044a625d16790ce6d..0207fcda9e880ea6525550ae6b8f3d8a176ca0b3 100644 (file)
@@ -50,6 +50,7 @@
 use syntax::ext::base::MacroKind;
 use syntax::source_map::FileName;
 use syntax::feature_gate::UnstableFeatures;
+use syntax::symbol::{Symbol, sym};
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
 use rustc::middle::privacy::AccessLevels;
 use rustc::middle::stability;
@@ -571,24 +572,24 @@ pub fn run(mut krate: clean::Crate,
     // Crawl the crate attributes looking for attributes which control how we're
     // going to emit HTML
     if let Some(attrs) = krate.module.as_ref().map(|m| &m.attrs) {
-        for attr in attrs.lists("doc") {
-            match (attr.name_or_empty().get(), attr.value_str()) {
-                ("html_favicon_url", Some(s)) => {
+        for attr in attrs.lists(sym::doc) {
+            match (attr.name_or_empty(), attr.value_str()) {
+                (sym::html_favicon_url, Some(s)) => {
                     scx.layout.favicon = s.to_string();
                 }
-                ("html_logo_url", Some(s)) => {
+                (sym::html_logo_url, Some(s)) => {
                     scx.layout.logo = s.to_string();
                 }
-                ("html_playground_url", Some(s)) => {
+                (sym::html_playground_url, Some(s)) => {
                     markdown::PLAYGROUND.with(|slot| {
                         let name = krate.name.clone();
                         *slot.borrow_mut() = Some((Some(name), s.to_string()));
                     });
                 }
-                ("issue_tracker_base_url", Some(s)) => {
+                (sym::issue_tracker_base_url, Some(s)) => {
                     scx.issue_tracker_base_url = Some(s.to_string());
                 }
-                ("html_no_source", None) if attr.is_word() => {
+                (sym::html_no_source, None) if attr.is_word() => {
                     scx.include_sources = false;
                 }
                 _ => {}
@@ -1388,8 +1389,8 @@ fn extern_location(e: &clean::ExternalCrate, extern_url: Option<&str>, dst: &Pat
 
     // Failing that, see if there's an attribute specifying where to find this
     // external crate
-    e.attrs.lists("doc")
-     .filter(|a| a.check_name("html_root_url"))
+    e.attrs.lists(sym::doc)
+     .filter(|a| a.check_name(sym::html_root_url))
      .filter_map(|a| a.value_str())
      .map(|url| {
         let mut url = url.to_string();
@@ -1779,8 +1780,8 @@ fn add_aliases(&mut self, item: &clean::Item) {
             let path = self.paths.get(&item.def_id)
                                  .map(|p| p.0[..p.0.len() - 1].join("::"))
                                  .unwrap_or("std".to_owned());
-            for alias in item.attrs.lists("doc")
-                                   .filter(|a| a.check_name("alias"))
+            for alias in item.attrs.lists(sym::doc)
+                                   .filter(|a| a.check_name(sym::alias))
                                    .filter_map(|a| a.value_str()
                                                     .map(|s| s.to_string().replace("\"", "")))
                                    .filter(|v| !v.is_empty())
@@ -3761,22 +3762,22 @@ fn render_attribute(attr: &ast::MetaItem) -> Option<String> {
     }
 }
 
-const ATTRIBUTE_WHITELIST: &'static [&'static str] = &[
-    "export_name",
-    "lang",
-    "link_section",
-    "must_use",
-    "no_mangle",
-    "repr",
-    "unsafe_destructor_blind_to_params",
-    "non_exhaustive"
+const ATTRIBUTE_WHITELIST: &'static [Symbol] = &[
+    sym::export_name,
+    sym::lang,
+    sym::link_section,
+    sym::must_use,
+    sym::no_mangle,
+    sym::repr,
+    sym::unsafe_destructor_blind_to_params,
+    sym::non_exhaustive
 ];
 
 fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item) -> fmt::Result {
     let mut attrs = String::new();
 
     for attr in &it.attrs.other_attrs {
-        if !ATTRIBUTE_WHITELIST.contains(&attr.name_or_empty().get()) {
+        if !ATTRIBUTE_WHITELIST.contains(&attr.name_or_empty()) {
             continue;
         }
         if let Some(s) = render_attribute(&attr.meta().unwrap()) {
index fe407fa24d93e3932256a45d8018845f9d598159..4ee09f7096b6163a90162d7057085d80b3aa658f 100644 (file)
@@ -5,6 +5,7 @@
 
 use syntax::attr;
 use syntax_pos::FileName;
+use syntax::symbol::sym;
 
 use std::collections::BTreeMap;
 use std::ops;
@@ -131,7 +132,7 @@ fn fold_item(&mut self, i: clean::Item) -> Option<clean::Item> {
                 return Some(i);
             }
             clean::ImplItem(ref impl_)
-                if attr::contains_name(&i.attrs.other_attrs, "automatically_derived")
+                if attr::contains_name(&i.attrs.other_attrs, sym::automatically_derived)
                     || impl_.synthetic || impl_.blanket_impl.is_some() =>
             {
                 // built-in derives get the `#[automatically_derived]` attribute, and
index abf19a0a5efa4cca9346102bdd1d44dd4c52f5b1..9e108e605c8bba9fc42a9f57cb2a22a519fe911d 100644 (file)
@@ -99,7 +99,7 @@ fn resolve(&self,
             // Try looking for methods and associated items.
             let mut split = path_str.rsplitn(2, "::");
             let item_name = if let Some(first) = split.next() {
-                first
+                Symbol::intern(first)
             } else {
                 return Err(())
             };
index 8d33cd72e29aad0eab1f3a1557271f160e36f62b..70cd4b72199bca2f73a97531f38fd02c9201032b 100644 (file)
@@ -5,6 +5,7 @@
 
 use rustc::util::nodemap::FxHashSet;
 use rustc::hir::def_id::DefId;
+use syntax::symbol::sym;
 
 pub const COLLECT_TRAIT_IMPLS: Pass = Pass {
     name: "collect-trait-impls",
@@ -68,7 +69,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
             inline::build_impl(cx, def_id, &mut new_items);
 
             // FIXME(eddyb) is this `doc(hidden)` check needed?
-            if !cx.tcx.get_attrs(def_id).lists("doc").has_word("hidden") {
+            if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) {
                 let self_ty = cx.tcx.type_of(def_id);
                 let impls = get_auto_trait_and_blanket_impls(cx, self_ty, def_id);
                 let mut renderinfo = cx.renderinfo.borrow_mut();
@@ -154,7 +155,7 @@ impl<'a, 'tcx> DocFolder for SyntheticImplCollector<'a, 'tcx> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
         if i.is_struct() || i.is_enum() || i.is_union() {
             // FIXME(eddyb) is this `doc(hidden)` check needed?
-            if !self.cx.tcx.get_attrs(i.def_id).lists("doc").has_word("hidden") {
+            if !self.cx.tcx.get_attrs(i.def_id).lists(sym::doc).has_word(sym::hidden) {
                 self.impls.extend(get_auto_trait_and_blanket_impls(
                     self.cx,
                     self.cx.tcx.type_of(i.def_id),
index 240299c212abc10f2ef1547ce7ec0ea719caf8b2..da8977544f64bc17da8a968c0252ad2f03581607 100644 (file)
@@ -1,5 +1,6 @@
 use rustc::util::nodemap::DefIdSet;
 use std::mem;
+use syntax::symbol::sym;
 
 use crate::clean::{self, AttributesExt, NestedAttributesExt};
 use crate::clean::Item;
@@ -37,7 +38,7 @@ struct Stripper<'a> {
 
 impl<'a> DocFolder for Stripper<'a> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
-        if i.attrs.lists("doc").has_word("hidden") {
+        if i.attrs.lists(sym::doc).has_word(sym::hidden) {
             debug!("strip_hidden: stripping {} {:?}", i.type_(), i.name);
             // use a dedicated hidden item for given item type if any
             match i.inner {
index 5c0a4da1cd7ef05515e6e683d0ca6af068b8f90a..e40dbe52ffe6423ecb9e259e7bfcd8b931a98088 100644 (file)
 use syntax::source_map::SourceMap;
 use syntax::edition::Edition;
 use syntax::feature_gate::UnstableFeatures;
-use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName};
-use tempfile::Builder as TempFileBuilder;
-use testing;
-
 use std::env;
 use std::io::prelude::*;
 use std::io;
 use std::process::Command;
 use std::str;
 use std::sync::{Arc, Mutex};
+use syntax::symbol::sym;
+use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName};
+use tempfile::Builder as TempFileBuilder;
+use testing;
 
 use crate::clean::Attributes;
 use crate::config::Options;
@@ -137,17 +137,17 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
     };
 
     let test_attrs: Vec<_> = krate.attrs.iter()
-        .filter(|a| a.check_name("doc"))
+        .filter(|a| a.check_name(sym::doc))
         .flat_map(|a| a.meta_item_list().unwrap_or_else(Vec::new))
-        .filter(|a| a.check_name("test"))
+        .filter(|a| a.check_name(sym::test))
         .collect();
     let attrs = test_attrs.iter().flat_map(|a| a.meta_item_list().unwrap_or(&[]));
 
     for attr in attrs {
-        if attr.check_name("no_crate_inject") {
+        if attr.check_name(sym::no_crate_inject) {
             opts.no_crate_inject = true;
         }
-        if attr.check_name("attr") {
+        if attr.check_name(sym::attr) {
             if let Some(l) = attr.meta_item_list() {
                 for item in l {
                     opts.attrs.push(pprust::meta_list_item_to_string(item));
index 94d2d7ffdb8c2bb14b4f7c93566ecfc88f583feb..eb9de43e388618ab67736d4812da305bf3832817 100644 (file)
@@ -10,6 +10,7 @@
 use syntax::attr;
 use syntax::ext::base::MacroKind;
 use syntax::source_map::Spanned;
+use syntax::symbol::sym;
 use syntax_pos::{self, Span};
 
 use std::mem;
@@ -165,11 +166,11 @@ pub fn visit_fn(&mut self, om: &mut Module, item: &hir::Item,
                     body: hir::BodyId) {
         debug!("Visiting fn");
         let macro_kind = item.attrs.iter().filter_map(|a| {
-            if a.check_name("proc_macro") {
+            if a.check_name(sym::proc_macro) {
                 Some(MacroKind::Bang)
-            } else if a.check_name("proc_macro_derive") {
+            } else if a.check_name(sym::proc_macro_derive) {
                 Some(MacroKind::Derive)
-            } else if a.check_name("proc_macro_attribute") {
+            } else if a.check_name(sym::proc_macro_attribute) {
                 Some(MacroKind::Attr)
             } else {
                 None
@@ -178,7 +179,7 @@ pub fn visit_fn(&mut self, om: &mut Module, item: &hir::Item,
         match macro_kind {
             Some(kind) => {
                 let name = if kind == MacroKind::Derive {
-                    item.attrs.lists("proc_macro_derive")
+                    item.attrs.lists(sym::proc_macro_derive)
                               .filter_map(|mi| mi.ident())
                               .next()
                               .expect("proc-macro derives require a name")
@@ -188,8 +189,8 @@ pub fn visit_fn(&mut self, om: &mut Module, item: &hir::Item,
                 };
 
                 let mut helpers = Vec::new();
-                for mi in item.attrs.lists("proc_macro_derive") {
-                    if !mi.check_name("attributes") {
+                for mi in item.attrs.lists(sym::proc_macro_derive) {
+                    if !mi.check_name(sym::attributes) {
                         continue;
                     }
 
@@ -274,7 +275,8 @@ fn maybe_inline_local(&mut self,
         fn inherits_doc_hidden(cx: &core::DocContext<'_>, mut node: hir::HirId) -> bool {
             while let Some(id) = cx.tcx.hir().get_enclosing_scope(node) {
                 node = id;
-                if cx.tcx.hir().attrs_by_hir_id(node).lists("doc").has_word("hidden") {
+                if cx.tcx.hir().attrs_by_hir_id(node)
+                    .lists(sym::doc).has_word(sym::hidden) {
                     return true;
                 }
                 if node == hir::CRATE_HIR_ID {
@@ -295,8 +297,8 @@ fn inherits_doc_hidden(cx: &core::DocContext<'_>, mut node: hir::HirId) -> bool
 
         let use_attrs = tcx.hir().attrs_by_hir_id(id);
         // Don't inline `doc(hidden)` imports so they can be stripped at a later stage.
-        let is_no_inline = use_attrs.lists("doc").has_word("no_inline") ||
-                           use_attrs.lists("doc").has_word("hidden");
+        let is_no_inline = use_attrs.lists(sym::doc).has_word(sym::no_inline) ||
+                           use_attrs.lists(sym::doc).has_word(sym::hidden);
 
         // For cross-crate impl inlining we need to know whether items are
         // reachable in documentation -- a previously nonreachable item can be
@@ -304,7 +306,7 @@ fn inherits_doc_hidden(cx: &core::DocContext<'_>, mut node: hir::HirId) -> bool
         // (this is done here because we need to know this upfront).
         if !res_did.is_local() && !is_no_inline {
             let attrs = clean::inline::load_attrs(self.cx, res_did);
-            let self_is_hidden = attrs.lists("doc").has_word("hidden");
+            let self_is_hidden = attrs.lists(sym::doc).has_word(sym::hidden);
             match res {
                 Res::Def(DefKind::Trait, did) |
                 Res::Def(DefKind::Struct, did) |
@@ -432,8 +434,8 @@ pub fn visit_item(&mut self, item: &hir::Item,
                 if item.vis.node.is_pub() && self.inside_public_path {
                     let please_inline = item.attrs.iter().any(|item| {
                         match item.meta_item_list() {
-                            Some(ref list) if item.check_name("doc") => {
-                                list.iter().any(|i| i.check_name("inline"))
+                            Some(ref list) if item.check_name(sym::doc) => {
+                                list.iter().any(|i| i.check_name(sym::inline))
                             }
                             _ => false,
                         }
index 326c9a10f7df839ec2ed2cc4d28ebbdf264333a2..2547e3a06e9efbbe71b1e309c23cc9ecb1679fe0 100644 (file)
@@ -3,6 +3,7 @@
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
 use rustc::ty::Visibility;
 use rustc::util::nodemap::FxHashSet;
+use syntax::symbol::sym;
 
 use std::cell::RefMut;
 
@@ -42,7 +43,7 @@ pub fn visit_lib(&mut self, cnum: CrateNum) {
 
     // Updates node level and returns the updated level
     fn update(&mut self, did: DefId, level: Option<AccessLevel>) -> Option<AccessLevel> {
-        let is_hidden = self.cx.tcx.get_attrs(did).lists("doc").has_word("hidden");
+        let is_hidden = self.cx.tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden);
 
         let old_level = self.access_levels.map.get(&did).cloned();
         // Accessibility levels can only grow
index 726c27321538d2024dfd7944ce563eb38f771db5..7a6c97ebaa226093156aadc472cc93f95e6d9254 100644 (file)
@@ -20,8 +20,7 @@ fn main() {
     } else if target.contains("netbsd") {
         println!("cargo:rustc-link-lib=pthread");
         println!("cargo:rustc-link-lib=rt");
-    } else if target.contains("dragonfly") || target.contains("bitrig") ||
-              target.contains("openbsd") {
+    } else if target.contains("dragonfly") || target.contains("openbsd") {
         println!("cargo:rustc-link-lib=pthread");
     } else if target.contains("solaris") {
         println!("cargo:rustc-link-lib=socket");
index c0d0c23e469680c24b7ddf37fba83c67b47a795a..260624a8bd8594945fde8d6923159bad3b31c7dc 100644 (file)
@@ -746,6 +746,10 @@ fn next(&mut self) -> Option<String> {
         self.inner.next().map(|s| s.into_string().unwrap())
     }
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+    #[inline]
+    fn last(mut self) -> Option<String> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "env", since = "1.0.0")]
@@ -781,6 +785,8 @@ impl Iterator for ArgsOs {
     type Item = OsString;
     fn next(&mut self) -> Option<OsString> { self.inner.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+    #[inline]
+    fn last(mut self) -> Option<OsString> { self.next_back() }
 }
 
 #[stable(feature = "env", since = "1.0.0")]
@@ -845,7 +851,6 @@ pub mod consts {
     /// - ios
     /// - freebsd
     /// - dragonfly
-    /// - bitrig
     /// - netbsd
     /// - openbsd
     /// - solaris
index 081fff0562b162c224b66177de7f870b1aae299b..7cb830e751a77653295b4bcb0f6f6e8d9bb8d48c 100644 (file)
@@ -197,7 +197,10 @@ fn cause(&self) -> Option<&dyn Error> {
     fn source(&self) -> Option<&(dyn Error + 'static)> { None }
 
     /// Gets the `TypeId` of `self`
-    #[stable(feature = "error_type_id", since = "1.34.0")]
+    #[doc(hidden)]
+    #[unstable(feature = "error_type_id",
+               reason = "this is memory unsafe to override in user code",
+               issue = "60784")]
     fn type_id(&self) -> TypeId where Self: 'static {
         TypeId::of::<Self>()
     }
index f93583dff818f115329faf35ffae148466b742f6..5c6c43017cf6402be3528a88c17dde88ad3fb055 100644 (file)
@@ -43,7 +43,9 @@
 /// `CString` implements a [`as_ptr`] method through the [`Deref`]
 /// trait. This method will give you a `*const c_char` which you can
 /// feed directly to extern functions that expect a nul-terminated
-/// string, like C's `strdup()`.
+/// string, like C's `strdup()`. Notice that [`as_ptr`] returns a
+/// read-only pointer; if the C code writes to it, that causes
+/// undefined behavior.
 ///
 /// # Extracting a slice of the whole C string
 ///
@@ -61,7 +63,7 @@
 ///
 /// Once you have the kind of slice you need (with or without a nul
 /// terminator), you can call the slice's own
-/// [`as_ptr`][slice.as_ptr] method to get a raw pointer to pass to
+/// [`as_ptr`][slice.as_ptr] method to get a read-only raw pointer to pass to
 /// extern functions. See the documentation for that function for a
 /// discussion on ensuring the lifetime of the raw pointer.
 ///
@@ -1043,6 +1045,9 @@ pub fn from_bytes_with_nul(bytes: &[u8])
     ///
     /// **WARNING**
     ///
+    /// The returned pointer is read-only; writing to it (including passing it
+    /// to C code that writes to it) causes undefined behavior.
+    ///
     /// It is your responsibility to make sure that the underlying memory is not
     /// freed too early. For example, the following code will cause undefined
     /// behavior when `ptr` is used inside the `unsafe` block:
index ec54d8a042a3c10cf7dfab90892b959f4f13c8f7..e7923e381f1407205c647012acf15c81aab40644 100644 (file)
@@ -974,9 +974,9 @@ fn to_socket_addr_string() {
         // s has been moved into the tsa call
     }
 
-    // FIXME: figure out why this fails on openbsd and bitrig and fix it
+    // FIXME: figure out why this fails on openbsd and fix it
     #[test]
-    #[cfg(not(any(windows, target_os = "openbsd", target_os = "bitrig")))]
+    #[cfg(not(any(windows, target_os = "openbsd")))]
     fn to_socket_addr_str_bad() {
         assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err());
     }
index 0460ac9d7535439b53d02d53692d6a17a5f62275..cdffa390223a2c48fa0a458d88bfcc3de3819686 100644 (file)
@@ -1595,9 +1595,9 @@ fn render_inner(addr: &dyn crate::os::windows::io::AsRawSocket) -> impl fmt::Deb
         assert_eq!(format!("{:?}", stream), compare);
     }
 
-    // FIXME: re-enabled bitrig/openbsd tests once their socket timeout code
+    // FIXME: re-enabled openbsd tests once their socket timeout code
     //        no longer has rounding errors.
-    #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)]
+    #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd"), ignore)]
     #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
     #[test]
     fn timeouts() {
index d4187d2932b1289a78fefc7c3e6bfc323009e980..61d9149952ee5e2994119d13606c46f2b66fff0d 100644 (file)
@@ -1024,9 +1024,9 @@ fn debug() {
         assert_eq!(format!("{:?}", udpsock), compare);
     }
 
-    // FIXME: re-enabled bitrig/openbsd/netbsd tests once their socket timeout code
+    // FIXME: re-enabled openbsd/netbsd tests once their socket timeout code
     //        no longer has rounding errors.
-    #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)]
+    #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd"), ignore)]
     #[test]
     fn timeouts() {
         let addr = next_test_ip4();
diff --git a/src/libstd/os/bitrig/fs.rs b/src/libstd/os/bitrig/fs.rs
deleted file mode 100644 (file)
index b5c6903..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-#![stable(feature = "metadata_ext", since = "1.1.0")]
-
-use crate::fs::Metadata;
-use crate::sys_common::AsInner;
-
-#[allow(deprecated)]
-use crate::os::bitrig::raw;
-
-/// OS-specific extensions to [`fs::Metadata`].
-///
-/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
-#[stable(feature = "metadata_ext", since = "1.1.0")]
-pub trait MetadataExt {
-    /// Gain a reference to the underlying `stat` structure which contains
-    /// the raw information returned by the OS.
-    ///
-    /// The contents of the returned `stat` are **not** consistent across
-    /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
-    /// cross-Unix abstractions contained within the raw stat.
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    #[rustc_deprecated(since = "1.8.0",
-                       reason = "deprecated in favor of the accessor \
-                                 methods of this trait")]
-    #[allow(deprecated)]
-    fn as_raw_stat(&self) -> &raw::stat;
-
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_dev(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_ino(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_mode(&self) -> u32;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_nlink(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_uid(&self) -> u32;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_gid(&self) -> u32;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_rdev(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_size(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_atime(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_atime_nsec(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_mtime(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_mtime_nsec(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_ctime(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_ctime_nsec(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_birthtime(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_birthtime_nsec(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_blksize(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_blocks(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_flags(&self) -> u32;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_gen(&self) -> u32;
-}
-
-#[stable(feature = "metadata_ext", since = "1.1.0")]
-impl MetadataExt for Metadata {
-    #[allow(deprecated)]
-    fn as_raw_stat(&self) -> &raw::stat {
-        unsafe {
-            &*(self.as_inner().as_inner() as *const libc::stat
-                                          as *const raw::stat)
-        }
-    }
-    fn st_dev(&self) -> u64 {
-        self.as_inner().as_inner().st_dev as u64
-    }
-    fn st_ino(&self) -> u64 {
-        self.as_inner().as_inner().st_ino as u64
-    }
-    fn st_mode(&self) -> u32 {
-        self.as_inner().as_inner().st_mode as u32
-    }
-    fn st_nlink(&self) -> u64 {
-        self.as_inner().as_inner().st_nlink as u64
-    }
-    fn st_uid(&self) -> u32 {
-        self.as_inner().as_inner().st_uid as u32
-    }
-    fn st_gid(&self) -> u32 {
-        self.as_inner().as_inner().st_gid as u32
-    }
-    fn st_rdev(&self) -> u64 {
-        self.as_inner().as_inner().st_rdev as u64
-    }
-    fn st_size(&self) -> u64 {
-        self.as_inner().as_inner().st_size as u64
-    }
-    fn st_atime(&self) -> i64 {
-        self.as_inner().as_inner().st_atime as i64
-    }
-    fn st_atime_nsec(&self) -> i64 {
-        self.as_inner().as_inner().st_atime_nsec as i64
-    }
-    fn st_mtime(&self) -> i64 {
-        self.as_inner().as_inner().st_mtime as i64
-    }
-    fn st_mtime_nsec(&self) -> i64 {
-        self.as_inner().as_inner().st_mtime_nsec as i64
-    }
-    fn st_ctime(&self) -> i64 {
-        self.as_inner().as_inner().st_ctime as i64
-    }
-    fn st_ctime_nsec(&self) -> i64 {
-        self.as_inner().as_inner().st_ctime_nsec as i64
-    }
-    fn st_birthtime(&self) -> i64 {
-        self.as_inner().as_inner().st_birthtime as i64
-    }
-    fn st_birthtime_nsec(&self) -> i64 {
-        self.as_inner().as_inner().st_birthtime_nsec as i64
-    }
-    fn st_blksize(&self) -> u64 {
-        self.as_inner().as_inner().st_blksize as u64
-    }
-    fn st_blocks(&self) -> u64 {
-        self.as_inner().as_inner().st_blocks as u64
-    }
-    fn st_gen(&self) -> u32 {
-        self.as_inner().as_inner().st_gen as u32
-    }
-    fn st_flags(&self) -> u32 {
-        self.as_inner().as_inner().st_flags as u32
-    }
-}
diff --git a/src/libstd/os/bitrig/mod.rs b/src/libstd/os/bitrig/mod.rs
deleted file mode 100644 (file)
index 0bc105b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-//! Bitrig-specific definitions
-
-#![stable(feature = "raw_ext", since = "1.1.0")]
-
-pub mod raw;
-pub mod fs;
diff --git a/src/libstd/os/bitrig/raw.rs b/src/libstd/os/bitrig/raw.rs
deleted file mode 100644 (file)
index c966d5a..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-//! Bitrig-specific raw type definitions
-
-#![stable(feature = "raw_ext", since = "1.1.0")]
-#![rustc_deprecated(since = "1.8.0",
-                    reason = "these type aliases are no longer supported by \
-                              the standard library, the `libc` crate on \
-                              crates.io should be used instead for the correct \
-                              definitions")]
-#![allow(deprecated)]
-
-use crate::os::raw::c_long;
-use crate::os::unix::raw::{uid_t, gid_t};
-
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
-
-#[stable(feature = "pthread_t", since = "1.8.0")]
-pub type pthread_t = usize;
-
-#[repr(C)]
-#[derive(Clone)]
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub struct stat {
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_mode: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_dev: i32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_ino: u64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_nlink: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_uid: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_gid: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_rdev: i32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_atime: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_atime_nsec: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_mtime: u64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_mtime_nsec: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_ctime: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_ctime_nsec: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_size: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_blocks: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_blksize: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_flags: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_gen: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_birthtime: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_birthtime_nsec: i64,
-}
index 7b56d6d62cf2f5367240762f93ad1a582dab14e6..44cbc180b8b01563d280ff0e9958d9abd86cb15d 100644 (file)
@@ -39,7 +39,6 @@
 }
 
 #[cfg(target_os = "android")]    pub mod android;
-#[cfg(target_os = "bitrig")]     pub mod bitrig;
 #[cfg(target_os = "dragonfly")]  pub mod dragonfly;
 #[cfg(target_os = "freebsd")]    pub mod freebsd;
 #[cfg(target_os = "haiku")]      pub mod haiku;
index 126bc3754dabcac134e18c713c3d967878439aa3..59f9e439add244a4955c74191188b02d15740582 100644 (file)
@@ -888,6 +888,11 @@ impl<'a> Iterator for Iter<'a> {
     fn next(&mut self) -> Option<&'a OsStr> {
         self.inner.next().map(Component::as_os_str)
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a OsStr> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -951,6 +956,11 @@ fn next(&mut self) -> Option<Component<'a>> {
         }
         None
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
index 18de1096df2a208a3121447a8548c0ff804c7b72..6ba947d4598b1da1163214923bbf24dbacc854c8 100644 (file)
@@ -35,6 +35,8 @@ impl Iterator for Args {
     type Item = OsString;
     fn next(&mut self) -> Option<OsString> { self.iter.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+    #[inline]
+    fn last(mut self) -> Option<OsString> { self.next_back() }
 }
 
 impl ExactSizeIterator for Args {
@@ -49,7 +51,6 @@ fn next_back(&mut self) -> Option<OsString> { self.iter.next_back() }
           target_os = "android",
           target_os = "freebsd",
           target_os = "dragonfly",
-          target_os = "bitrig",
           target_os = "netbsd",
           target_os = "openbsd",
           target_os = "solaris",
index f9592d5c45f949c8d9933a33f906291794c61e82..891013406a1699cead6ea8630ba4ba89a96b1e58 100644 (file)
@@ -53,17 +53,6 @@ pub mod os {
     pub const EXE_EXTENSION: &str = "";
 }
 
-#[cfg(target_os = "bitrig")]
-pub mod os {
-    pub const FAMILY: &str = "unix";
-    pub const OS: &str = "bitrig";
-    pub const DLL_PREFIX: &str = "lib";
-    pub const DLL_SUFFIX: &str = ".so";
-    pub const DLL_EXTENSION: &str = "so";
-    pub const EXE_SUFFIX: &str = "";
-    pub const EXE_EXTENSION: &str = "";
-}
-
 #[cfg(target_os = "netbsd")]
 pub mod os {
     pub const FAMILY: &str = "unix";
index 45a850aa4a85c61d40f522d4339993a46428acd8..3ccb0a1b1abc7c547b023be8dc0a67c0f24fd55e 100644 (file)
@@ -32,12 +32,12 @@ mod libc {
 #[cfg(any(target_os = "linux", target_os = "android",
           target_os = "dragonfly", target_os = "freebsd",
           target_os = "openbsd", target_os = "netbsd",
-          target_os = "haiku", target_os = "bitrig"))]
+          target_os = "haiku"))]
 use libc::MSG_NOSIGNAL;
 #[cfg(not(any(target_os = "linux", target_os = "android",
               target_os = "dragonfly", target_os = "freebsd",
               target_os = "openbsd", target_os = "netbsd",
-              target_os = "haiku", target_os = "bitrig")))]
+              target_os = "haiku")))]
 const MSG_NOSIGNAL: libc::c_int = 0x0;
 
 fn sun_path_offset() -> usize {
index 22c05a72a91c04289865bc57a72ef215d94a605c..cc1f0790d4334fbb3266a6abe70e942eb9d5aa32 100644 (file)
@@ -147,8 +147,7 @@ pub fn accessed(&self) -> io::Result<SystemTime> {
         }))
     }
 
-    #[cfg(any(target_os = "bitrig",
-              target_os = "freebsd",
+    #[cfg(any(target_os = "freebsd",
               target_os = "openbsd",
               target_os = "macos",
               target_os = "ios"))]
@@ -159,8 +158,7 @@ pub fn created(&self) -> io::Result<SystemTime> {
         }))
     }
 
-    #[cfg(not(any(target_os = "bitrig",
-                  target_os = "freebsd",
+    #[cfg(not(any(target_os = "freebsd",
                   target_os = "openbsd",
                   target_os = "macos",
                   target_os = "ios")))]
@@ -355,7 +353,6 @@ pub fn ino(&self) -> u64 {
 
     #[cfg(any(target_os = "freebsd",
               target_os = "openbsd",
-              target_os = "bitrig",
               target_os = "netbsd",
               target_os = "dragonfly"))]
     pub fn ino(&self) -> u64 {
@@ -367,8 +364,7 @@ pub fn ino(&self) -> u64 {
               target_os = "netbsd",
               target_os = "openbsd",
               target_os = "freebsd",
-              target_os = "dragonfly",
-              target_os = "bitrig"))]
+              target_os = "dragonfly"))]
     fn name_bytes(&self) -> &[u8] {
         use crate::slice;
         unsafe {
index 90e26449ae280096dd5699700eb17a728294d177..c2b264ff8de1154788c3cbce34ff466732ba0c30 100644 (file)
@@ -5,7 +5,6 @@
 #[cfg(any(rustdoc, target_os = "linux"))] pub use crate::os::linux as platform;
 
 #[cfg(all(not(rustdoc), target_os = "android"))]   pub use crate::os::android as platform;
-#[cfg(all(not(rustdoc), target_os = "bitrig"))]    pub use crate::os::bitrig as platform;
 #[cfg(all(not(rustdoc), target_os = "dragonfly"))] pub use crate::os::dragonfly as platform;
 #[cfg(all(not(rustdoc), target_os = "freebsd"))]   pub use crate::os::freebsd as platform;
 #[cfg(all(not(rustdoc), target_os = "haiku"))]     pub use crate::os::haiku as platform;
index 726b17969b7c3e9b4f41274709ff4e4944d8836f..dad19eabf7db79bd87ba8827dc8e45f2ab1c9bf4 100644 (file)
@@ -33,8 +33,7 @@
                    target_os = "fuchsia",
                    target_os = "l4re"),
                link_name = "__errno_location")]
-    #[cfg_attr(any(target_os = "bitrig",
-                   target_os = "netbsd",
+    #[cfg_attr(any(target_os = "netbsd",
                    target_os = "openbsd",
                    target_os = "android",
                    target_os = "hermit",
@@ -257,7 +256,7 @@ fn procfs() -> io::Result<PathBuf> {
     sysctl().or_else(|_| procfs())
 }
 
-#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
+#[cfg(target_os = "openbsd")]
 pub fn current_exe() -> io::Result<PathBuf> {
     unsafe {
         let mut mib = [libc::CTL_KERN,
index e923b9aa29b0117d0d4144f9539e4ba0fd245241..77f1439e17b10324c7d67d25ab036d7755a27922 100644 (file)
@@ -13,7 +13,6 @@ pub fn hashmap_random_keys() -> (u64, u64) {
 
 #[cfg(all(unix,
           not(target_os = "ios"),
-          not(all(target_os = "macos", miri)),
           not(target_os = "openbsd"),
           not(target_os = "freebsd"),
           not(target_os = "fuchsia")))]
@@ -107,9 +106,7 @@ pub fn fill_bytes(v: &mut [u8]) {
 // once per thread in `hashmap_random_keys`. Therefore `SecRandomCopyBytes` is
 // only used on iOS where direct access to `/dev/urandom` is blocked by the
 // sandbox.
-// HACK: However, we do use this when running in Miri on macOS; intercepting this is much
-// easier than intercepting accesses to /dev/urandom.
-#[cfg(any(target_os = "ios", all(target_os = "macos", miri)))]
+#[cfg(target_os = "ios")]
 mod imp {
     use crate::io;
     use crate::ptr;
index 561279e82785c317429a7cb0ce075581f93d5d0b..fe1095fa0c2f65596fba38711f38cbb1b43b0fd4 100644 (file)
@@ -25,7 +25,6 @@ fn drop(&mut self) {
 
 #[cfg(any(target_os = "linux",
           target_os = "macos",
-          target_os = "bitrig",
           target_os = "dragonfly",
           target_os = "freebsd",
           target_os = "solaris",
@@ -139,7 +138,6 @@ unsafe fn get_stackp() -> *mut libc::c_void {
 
     #[cfg(any(target_os = "linux",
               target_os = "macos",
-              target_os = "bitrig",
               target_os = "freebsd",
               target_os = "netbsd",
               target_os = "openbsd",
@@ -185,7 +183,6 @@ pub unsafe fn drop_handler(handler: &mut Handler) {
 
 #[cfg(not(any(target_os = "linux",
               target_os = "macos",
-              target_os = "bitrig",
               target_os = "dragonfly",
               target_os = "freebsd",
               target_os = "solaris",
index f7d604ac4c8c1d95570addc93c27987f51b9a2fa..f4a1783ce8903d202fe5cafe2d1e8b25148caa3c 100644 (file)
@@ -99,7 +99,6 @@ pub fn set_name(name: &CStr) {
 
     #[cfg(any(target_os = "freebsd",
               target_os = "dragonfly",
-              target_os = "bitrig",
               target_os = "openbsd"))]
     pub fn set_name(name: &CStr) {
         unsafe {
@@ -189,7 +188,6 @@ fn drop(&mut self) {
 #[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))),
           not(target_os = "freebsd"),
           not(target_os = "macos"),
-          not(target_os = "bitrig"),
           not(all(target_os = "netbsd", not(target_vendor = "rumprun"))),
           not(target_os = "openbsd"),
           not(target_os = "solaris")))]
@@ -205,7 +203,6 @@ pub unsafe fn init() -> Option<Guard> { None }
 #[cfg(any(all(target_os = "linux", not(target_env = "musl")),
           target_os = "freebsd",
           target_os = "macos",
-          target_os = "bitrig",
           all(target_os = "netbsd", not(target_vendor = "rumprun")),
           target_os = "openbsd",
           target_os = "solaris"))]
@@ -236,16 +233,15 @@ unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
         Some(stackaddr as *mut libc::c_void)
     }
 
-    #[cfg(any(target_os = "openbsd", target_os = "bitrig"))]
+    #[cfg(target_os = "openbsd")]
     unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
         let mut current_stack: libc::stack_t = crate::mem::zeroed();
         assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(),
                                              &mut current_stack), 0);
 
-        let extra = if cfg!(target_os = "bitrig") {3} else {1} * PAGE_SIZE;
         let stackaddr = if libc::pthread_main_np() == 1 {
             // main thread
-            current_stack.ss_sp as usize - current_stack.ss_size + extra
+            current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE
         } else {
             // new thread
             current_stack.ss_sp as usize - current_stack.ss_size
@@ -343,7 +339,6 @@ pub unsafe fn init() -> Option<Guard> {
     }
 
     #[cfg(any(target_os = "macos",
-              target_os = "bitrig",
               target_os = "openbsd",
               target_os = "solaris"))]
     pub unsafe fn current() -> Option<Guard> {
index b3c77b869956364326312711471bff4e66fa2556..6766099c1ece13d05520f6f5ba04ed1c453f7adc 100644 (file)
@@ -37,6 +37,10 @@ fn next(&mut self) -> Option<OsString> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+    #[inline]
+    fn last(mut self) -> Option<OsString> {
+        self.next_back()
+    }
 }
 
 impl ExactSizeIterator for Args {
index b04bb484eedb9499cf453c344749251be4fca405..744d7ec59d3a3e76303da40a4589bf099af936d1 100644 (file)
@@ -181,6 +181,8 @@ impl Iterator for Args {
     type Item = OsString;
     fn next(&mut self) -> Option<OsString> { self.parsed_args_list.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.parsed_args_list.size_hint() }
+    #[inline]
+    fn last(mut self) -> Option<OsString> { self.next_back() }
 }
 
 impl DoubleEndedIterator for Args {
index cf1dc20b52fc6c239cf7fdcac678c808e7eddada..391f670346f2ad92e1e63e98f8edf0b5dac44551 100644 (file)
 #[cfg(any(target_os = "linux", target_os = "android",
           target_os = "dragonfly", target_os = "freebsd",
           target_os = "openbsd", target_os = "netbsd",
-          target_os = "haiku", target_os = "bitrig"))]
+          target_os = "haiku"))]
 use libc::MSG_NOSIGNAL;
 #[cfg(not(any(target_os = "linux", target_os = "android",
               target_os = "dragonfly", target_os = "freebsd",
               target_os = "openbsd", target_os = "netbsd",
-              target_os = "haiku", target_os = "bitrig")))]
+              target_os = "haiku")))]
 const MSG_NOSIGNAL: c_int = 0x0;
 
 ////////////////////////////////////////////////////////////////////////////////
index af2302d24f5214724715608ca6f26d59ca482112..d12240655e6289abf36f3ac437870eb4be5c4458 100644 (file)
@@ -6,6 +6,7 @@
 pub use crate::util::parser::ExprPrecedence;
 
 use crate::ext::hygiene::{Mark, SyntaxContext};
+use crate::parse::token;
 use crate::print::pprust;
 use crate::ptr::P;
 use crate::source_map::{dummy_spanned, respan, Spanned};
@@ -80,12 +81,6 @@ fn eq(&self, symbol: &Symbol) -> bool {
     }
 }
 
-impl<'a> PartialEq<&'a str> for Path {
-    fn eq(&self, string: &&'a str) -> bool {
-        self.segments.len() == 1 && self.segments[0].ident.name == *string
-    }
-}
-
 impl fmt::Debug for Path {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "path({})", pprust::path_to_string(self))
@@ -1350,8 +1345,19 @@ pub enum StrStyle {
     Raw(u16),
 }
 
-/// A literal.
-pub type Lit = Spanned<LitKind>;
+/// An AST literal.
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+pub struct Lit {
+    /// The original literal token as written in source code.
+    pub token: token::Lit,
+    /// The original literal suffix as written in source code.
+    pub suffix: Option<Symbol>,
+    /// The "semantic" representation of the literal lowered from the original tokens.
+    /// Strings are unescaped, hexadecimal forms are eliminated, etc.
+    /// FIXME: Remove this and only create the semantic representation during lowering to HIR.
+    pub node: LitKind,
+    pub span: Span,
+}
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq)]
 pub enum LitIntType {
index db821f4e5369d2b0c971a6aca7d37988878fddba..65ca96afab1292be47cf18688b1f0708ec6da054 100644 (file)
@@ -5,7 +5,7 @@
 use crate::parse::ParseSess;
 
 use errors::{Applicability, Handler};
-use syntax_pos::{symbol::Symbol, Span};
+use syntax_pos::{symbol::Symbol, symbol::sym, Span};
 
 use super::{mark_used, MetaItemKind};
 
@@ -80,13 +80,13 @@ pub enum UnwindAttr {
 /// Determine what `#[unwind]` attribute is present in `attrs`, if any.
 pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Option<UnwindAttr> {
     attrs.iter().fold(None, |ia, attr| {
-        if attr.check_name("unwind") {
+        if attr.check_name(sym::unwind) {
             if let Some(meta) = attr.meta() {
                 if let MetaItemKind::List(items) = meta.node {
                     if items.len() == 1 {
-                        if items[0].check_name("allowed") {
+                        if items[0].check_name(sym::allowed) {
                             return Some(UnwindAttr::Allowed);
-                        } else if items[0].check_name("aborts") {
+                        } else if items[0].check_name(sym::aborts) {
                             return Some(UnwindAttr::Aborts);
                         }
                     }
@@ -153,9 +153,9 @@ pub struct RustcDeprecation {
 
 /// Checks if `attrs` contains an attribute like `#![feature(feature_name)]`.
 /// This will not perform any "sanity checks" on the form of the attributes.
-pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool {
+pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool {
     attrs.iter().any(|item| {
-        item.check_name("feature") &&
+        item.check_name(sym::feature) &&
         item.meta_item_list().map(|list| {
             list.iter().any(|mi| mi.is_word() && mi.check_name(feature_name))
         }).unwrap_or(false)
@@ -185,12 +185,12 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
 
     'outer: for attr in attrs_iter {
         if ![
-            "rustc_deprecated",
-            "rustc_const_unstable",
-            "unstable",
-            "stable",
-            "rustc_promotable",
-            "rustc_allow_const_fn_ptr",
+            sym::rustc_deprecated,
+            sym::rustc_const_unstable,
+            sym::unstable,
+            sym::stable,
+            sym::rustc_promotable,
+            sym::rustc_allow_const_fn_ptr,
         ].iter().any(|&s| attr.path == s) {
             continue // not a stability level
         }
@@ -199,10 +199,10 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
 
         let meta = attr.meta();
 
-        if attr.path == "rustc_promotable" {
+        if attr.path == sym::rustc_promotable {
             promotable = true;
         }
-        if attr.path == "rustc_allow_const_fn_ptr" {
+        if attr.path == sym::rustc_allow_const_fn_ptr {
             allow_const_fn_ptr = true;
         }
         // attributes with data
@@ -229,10 +229,9 @@ macro_rules! get_meta {
                     )+
                     for meta in metas {
                         if let Some(mi) = meta.meta_item() {
-                            match mi.name_or_empty().get() {
+                            match mi.name_or_empty() {
                                 $(
-                                    stringify!($name)
-                                        => if !get(mi, &mut $name) { continue 'outer },
+                                    sym::$name => if !get(mi, &mut $name) { continue 'outer },
                                 )+
                                 _ => {
                                     let expected = &[ $( stringify!($name) ),+ ];
@@ -259,8 +258,8 @@ macro_rules! get_meta {
                 }
             }
 
-            match meta.name_or_empty().get() {
-                "rustc_deprecated" => {
+            match meta.name_or_empty() {
+                sym::rustc_deprecated => {
                     if rustc_depr.is_some() {
                         span_err!(diagnostic, item_sp, E0540,
                                   "multiple rustc_deprecated attributes");
@@ -287,7 +286,7 @@ macro_rules! get_meta {
                         }
                     }
                 }
-                "rustc_const_unstable" => {
+                sym::rustc_const_unstable => {
                     if rustc_const_unstable.is_some() {
                         span_err!(diagnostic, item_sp, E0553,
                                   "multiple rustc_const_unstable attributes");
@@ -302,7 +301,7 @@ macro_rules! get_meta {
                         continue
                     }
                 }
-                "unstable" => {
+                sym::unstable => {
                     if stab.is_some() {
                         handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
                         break
@@ -313,10 +312,10 @@ macro_rules! get_meta {
                     let mut issue = None;
                     for meta in metas {
                         if let Some(mi) = meta.meta_item() {
-                            match mi.name_or_empty().get() {
-                                "feature" => if !get(mi, &mut feature) { continue 'outer },
-                                "reason" => if !get(mi, &mut reason) { continue 'outer },
-                                "issue" => if !get(mi, &mut issue) { continue 'outer },
+                            match mi.name_or_empty() {
+                                sym::feature => if !get(mi, &mut feature) { continue 'outer },
+                                sym::reason => if !get(mi, &mut reason) { continue 'outer },
+                                sym::issue => if !get(mi, &mut issue) { continue 'outer },
                                 _ => {
                                     handle_errors(
                                         sess,
@@ -374,7 +373,7 @@ macro_rules! get_meta {
                         }
                     }
                 }
-                "stable" => {
+                sym::stable => {
                     if stab.is_some() {
                         handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
                         break
@@ -385,11 +384,9 @@ macro_rules! get_meta {
                     for meta in metas {
                         match meta {
                             NestedMetaItem::MetaItem(mi) => {
-                                match mi.name_or_empty().get() {
-                                    "feature" =>
-                                        if !get(mi, &mut feature) { continue 'outer },
-                                    "since" =>
-                                        if !get(mi, &mut since) { continue 'outer },
+                                match mi.name_or_empty() {
+                                    sym::feature => if !get(mi, &mut feature) { continue 'outer },
+                                    sym::since => if !get(mi, &mut since) { continue 'outer },
                                     _ => {
                                         handle_errors(
                                             sess,
@@ -482,7 +479,7 @@ macro_rules! get_meta {
 }
 
 pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
-    super::first_attr_value_str_by_name(attrs, "crate_name")
+    super::first_attr_value_str_by_name(attrs, sym::crate_name)
 }
 
 /// Tests if a cfg-pattern matches the cfg set
@@ -542,14 +539,14 @@ pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F)
 
             // The unwraps below may look dangerous, but we've already asserted
             // that they won't fail with the loop above.
-            match cfg.name_or_empty().get() {
-                "any" => mis.iter().any(|mi| {
+            match cfg.name_or_empty() {
+                sym::any => mis.iter().any(|mi| {
                     eval_condition(mi.meta_item().unwrap(), sess, eval)
                 }),
-                "all" => mis.iter().all(|mi| {
+                sym::all => mis.iter().all(|mi| {
                     eval_condition(mi.meta_item().unwrap(), sess, eval)
                 }),
-                "not" => {
+                sym::not => {
                     if mis.len() != 1 {
                         span_err!(sess.span_diagnostic, cfg.span, E0536, "expected 1 cfg-pattern");
                         return false;
@@ -593,7 +590,7 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess,
     let diagnostic = &sess.span_diagnostic;
 
     'outer: for attr in attrs_iter {
-        if !attr.check_name("deprecated") {
+        if !attr.check_name(sym::deprecated) {
             continue;
         }
 
@@ -645,9 +642,9 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess,
                 for meta in list {
                     match meta {
                         NestedMetaItem::MetaItem(mi) => {
-                            match mi.name_or_empty().get() {
-                                "since" => if !get(mi, &mut since) { continue 'outer },
-                                "note" => if !get(mi, &mut note) { continue 'outer },
+                            match mi.name_or_empty() {
+                                sym::since => if !get(mi, &mut since) { continue 'outer },
+                                sym::note => if !get(mi, &mut note) { continue 'outer },
                                 _ => {
                                     handle_errors(
                                         sess,
@@ -721,7 +718,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> {
 
     let mut acc = Vec::new();
     let diagnostic = &sess.span_diagnostic;
-    if attr.path == "repr" {
+    if attr.path == sym::repr {
         if let Some(items) = attr.meta_item_list() {
             mark_used(attr);
             for item in items {
@@ -739,11 +736,11 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> {
 
                 let mut recognised = false;
                 if item.is_word() {
-                    let hint = match item.name_or_empty().get() {
-                        "C" => Some(ReprC),
-                        "packed" => Some(ReprPacked(1)),
-                        "simd" => Some(ReprSimd),
-                        "transparent" => Some(ReprTransparent),
+                    let hint = match item.name_or_empty() {
+                        sym::C => Some(ReprC),
+                        sym::packed => Some(ReprPacked(1)),
+                        sym::simd => Some(ReprSimd),
+                        sym::transparent => Some(ReprTransparent),
                         name => int_type_of_word(name).map(ReprInt),
                     };
 
@@ -770,14 +767,14 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> {
                     };
 
                     let mut literal_error = None;
-                    if name == "align" {
+                    if name == sym::align {
                         recognised = true;
                         match parse_alignment(&value.node) {
                             Ok(literal) => acc.push(ReprAlign(literal)),
                             Err(message) => literal_error = Some(message)
                         };
                     }
-                    else if name == "packed" {
+                    else if name == sym::packed {
                         recognised = true;
                         match parse_alignment(&value.node) {
                             Ok(literal) => acc.push(ReprPacked(literal)),
@@ -790,7 +787,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> {
                     }
                 } else {
                     if let Some(meta_item) = item.meta_item() {
-                        if meta_item.check_name("align") {
+                        if meta_item.check_name(sym::align) {
                             if let MetaItemKind::NameValue(ref value) = meta_item.node {
                                 recognised = true;
                                 let mut err = struct_span_err!(diagnostic, item.span(), E0693,
@@ -830,22 +827,22 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> {
     acc
 }
 
-fn int_type_of_word(s: &str) -> Option<IntType> {
+fn int_type_of_word(s: Symbol) -> Option<IntType> {
     use IntType::*;
 
     match s {
-        "i8" => Some(SignedInt(ast::IntTy::I8)),
-        "u8" => Some(UnsignedInt(ast::UintTy::U8)),
-        "i16" => Some(SignedInt(ast::IntTy::I16)),
-        "u16" => Some(UnsignedInt(ast::UintTy::U16)),
-        "i32" => Some(SignedInt(ast::IntTy::I32)),
-        "u32" => Some(UnsignedInt(ast::UintTy::U32)),
-        "i64" => Some(SignedInt(ast::IntTy::I64)),
-        "u64" => Some(UnsignedInt(ast::UintTy::U64)),
-        "i128" => Some(SignedInt(ast::IntTy::I128)),
-        "u128" => Some(UnsignedInt(ast::UintTy::U128)),
-        "isize" => Some(SignedInt(ast::IntTy::Isize)),
-        "usize" => Some(UnsignedInt(ast::UintTy::Usize)),
+        sym::i8 => Some(SignedInt(ast::IntTy::I8)),
+        sym::u8 => Some(UnsignedInt(ast::UintTy::U8)),
+        sym::i16 => Some(SignedInt(ast::IntTy::I16)),
+        sym::u16 => Some(UnsignedInt(ast::UintTy::U16)),
+        sym::i32 => Some(SignedInt(ast::IntTy::I32)),
+        sym::u32 => Some(UnsignedInt(ast::UintTy::U32)),
+        sym::i64 => Some(SignedInt(ast::IntTy::I64)),
+        sym::u64 => Some(UnsignedInt(ast::UintTy::U64)),
+        sym::i128 => Some(SignedInt(ast::IntTy::I128)),
+        sym::u128 => Some(UnsignedInt(ast::UintTy::U128)),
+        sym::isize => Some(SignedInt(ast::IntTy::Isize)),
+        sym::usize => Some(UnsignedInt(ast::UintTy::Usize)),
         _ => None
     }
 }
index e00f91e39528018e898756e2c7bd97f1899ccad4..d94a3165b0f1d1fdd50ca3da6f166ab28a56bec0 100644 (file)
 use crate::ast;
 use crate::ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment};
 use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem};
-use crate::ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam};
+use crate::ast::{Lit, LitKind, Expr, Item, Local, Stmt, StmtKind, GenericParam};
 use crate::mut_visit::visit_clobber;
-use crate::source_map::{BytePos, Spanned, respan, dummy_spanned};
+use crate::source_map::{BytePos, Spanned, dummy_spanned};
 use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
 use crate::parse::parser::Parser;
 use crate::parse::{self, ParseSess, PResult};
 use crate::parse::token::{self, Token};
 use crate::ptr::P;
-use crate::symbol::{keywords, LocalInternedString, Symbol};
+use crate::symbol::{keywords, Symbol};
 use crate::ThinVec;
 use crate::tokenstream::{TokenStream, TokenTree, DelimSpan};
 use crate::GLOBALS;
@@ -81,10 +81,7 @@ pub fn literal(&self) -> Option<&Lit> {
     }
 
     /// Returns `true` if this list item is a MetaItem with a name of `name`.
-    pub fn check_name<T>(&self, name: T) -> bool
-    where
-        Path: PartialEq<T>,
-    {
+    pub fn check_name(&self, name: Symbol) -> bool {
         self.meta_item().map_or(false, |meta_item| meta_item.check_name(name))
     }
 
@@ -92,8 +89,8 @@ pub fn check_name<T>(&self, name: T) -> bool
     pub fn ident(&self) -> Option<Ident> {
         self.meta_item().and_then(|meta_item| meta_item.ident())
     }
-    pub fn name_or_empty(&self) -> LocalInternedString {
-        self.ident().unwrap_or(keywords::Invalid.ident()).name.as_str()
+    pub fn name_or_empty(&self) -> Symbol {
+        self.ident().unwrap_or(keywords::Invalid.ident()).name
     }
 
     /// Gets the string value if self is a MetaItem and the MetaItem is a
@@ -154,10 +151,7 @@ impl Attribute {
     /// attribute is marked as used.
     ///
     /// To check the attribute name without marking it used, use the `path` field directly.
-    pub fn check_name<T>(&self, name: T) -> bool
-    where
-        Path: PartialEq<T>,
-    {
+    pub fn check_name(&self, name: Symbol) -> bool {
         let matches = self.path == name;
         if matches {
             mark_used(self);
@@ -173,8 +167,8 @@ pub fn ident(&self) -> Option<Ident> {
             None
         }
     }
-    pub fn name_or_empty(&self) -> LocalInternedString {
-        self.ident().unwrap_or(keywords::Invalid.ident()).name.as_str()
+    pub fn name_or_empty(&self) -> Symbol {
+        self.ident().unwrap_or(keywords::Invalid.ident()).name
     }
 
     pub fn value_str(&self) -> Option<Symbol> {
@@ -211,8 +205,8 @@ pub fn ident(&self) -> Option<Ident> {
             None
         }
     }
-    pub fn name_or_empty(&self) -> LocalInternedString {
-        self.ident().unwrap_or(keywords::Invalid.ident()).name.as_str()
+    pub fn name_or_empty(&self) -> Symbol {
+        self.ident().unwrap_or(keywords::Invalid.ident()).name
     }
 
     // #[attribute(name = "value")]
@@ -250,10 +244,7 @@ pub fn is_word(&self) -> bool {
         }
     }
 
-    pub fn check_name<T>(&self, name: T) -> bool
-    where
-        Path: PartialEq<T>,
-    {
+    pub fn check_name(&self, name: Symbol) -> bool {
         self.path == name
     }
 
@@ -350,12 +341,13 @@ pub fn with_desugared_doc<T, F>(&self, f: F) -> T where
 /* Constructors */
 
 pub fn mk_name_value_item_str(ident: Ident, value: Spanned<Symbol>) -> MetaItem {
-    let value = respan(value.span, LitKind::Str(value.node, ast::StrStyle::Cooked));
-    mk_name_value_item(ident.span.to(value.span), ident, value)
+    let lit_kind = LitKind::Str(value.node, ast::StrStyle::Cooked);
+    mk_name_value_item(ident.span.to(value.span), ident, lit_kind, value.span)
 }
 
-pub fn mk_name_value_item(span: Span, ident: Ident, value: ast::Lit) -> MetaItem {
-    MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) }
+pub fn mk_name_value_item(span: Span, ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem {
+    let lit = Lit::from_lit_kind(lit_kind, lit_span);
+    MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(lit) }
 }
 
 pub fn mk_list_item(span: Span, ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
@@ -417,7 +409,8 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute
 
 pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute {
     let style = doc_comment_style(&text.as_str());
-    let lit = respan(span, LitKind::Str(text, ast::StrStyle::Cooked));
+    let lit_kind = LitKind::Str(text, ast::StrStyle::Cooked);
+    let lit = Lit::from_lit_kind(lit_kind, span);
     Attribute {
         id,
         style,
@@ -428,28 +421,28 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute {
     }
 }
 
-pub fn list_contains_name(items: &[NestedMetaItem], name: &str) -> bool {
+pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool {
     items.iter().any(|item| {
         item.check_name(name)
     })
 }
 
-pub fn contains_name(attrs: &[Attribute], name: &str) -> bool {
+pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
     attrs.iter().any(|item| {
         item.check_name(name)
     })
 }
 
-pub fn find_by_name<'a>(attrs: &'a [Attribute], name: &str) -> Option<&'a Attribute> {
+pub fn find_by_name<'a>(attrs: &'a [Attribute], name: Symbol) -> Option<&'a Attribute> {
     attrs.iter().find(|attr| attr.check_name(name))
 }
 
-pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: &'a str)
+pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: Symbol)
     -> impl Iterator<Item = &'a Attribute> {
     attrs.iter().filter(move |attr| attr.check_name(name))
 }
 
-pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) -> Option<Symbol> {
+pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: Symbol) -> Option<Symbol> {
     attrs.iter()
         .find(|at| at.check_name(name))
         .and_then(|at| at.value_str())
@@ -561,8 +554,7 @@ fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItemKind>
             Some(TokenTree::Token(_, token::Eq)) => {
                 tokens.next();
                 return if let Some(TokenTree::Token(span, token)) = tokens.next() {
-                    LitKind::from_token(token)
-                        .map(|lit| MetaItemKind::NameValue(Spanned { node: lit, span: span }))
+                    Lit::from_token(&token, span, None).map(MetaItemKind::NameValue)
                 } else {
                     None
                 };
@@ -607,9 +599,9 @@ fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<NestedMetaItem>
         where I: Iterator<Item = TokenTree>,
     {
         if let Some(TokenTree::Token(span, token)) = tokens.peek().cloned() {
-            if let Some(node) = LitKind::from_token(token) {
+            if let Some(lit) = Lit::from_token(&token, span, None) {
                 tokens.next();
-                return Some(NestedMetaItem::Literal(respan(span, node)));
+                return Some(NestedMetaItem::Literal(lit));
             }
         }
 
@@ -617,81 +609,6 @@ fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<NestedMetaItem>
     }
 }
 
-impl Lit {
-    crate fn tokens(&self) -> TokenStream {
-        TokenTree::Token(self.span, self.node.token()).into()
-    }
-}
-
-impl LitKind {
-    fn token(&self) -> Token {
-        use std::ascii;
-
-        match *self {
-            LitKind::Str(string, ast::StrStyle::Cooked) => {
-                let escaped = string.as_str().escape_default().to_string();
-                Token::Literal(token::Lit::Str_(Symbol::intern(&escaped)), None)
-            }
-            LitKind::Str(string, ast::StrStyle::Raw(n)) => {
-                Token::Literal(token::Lit::StrRaw(string, n), None)
-            }
-            LitKind::ByteStr(ref bytes) => {
-                let string = bytes.iter().cloned().flat_map(ascii::escape_default)
-                    .map(Into::<char>::into).collect::<String>();
-                Token::Literal(token::Lit::ByteStr(Symbol::intern(&string)), None)
-            }
-            LitKind::Byte(byte) => {
-                let string: String = ascii::escape_default(byte).map(Into::<char>::into).collect();
-                Token::Literal(token::Lit::Byte(Symbol::intern(&string)), None)
-            }
-            LitKind::Char(ch) => {
-                let string: String = ch.escape_default().map(Into::<char>::into).collect();
-                Token::Literal(token::Lit::Char(Symbol::intern(&string)), None)
-            }
-            LitKind::Int(n, ty) => {
-                let suffix = match ty {
-                    ast::LitIntType::Unsigned(ty) => Some(Symbol::intern(ty.ty_to_string())),
-                    ast::LitIntType::Signed(ty) => Some(Symbol::intern(ty.ty_to_string())),
-                    ast::LitIntType::Unsuffixed => None,
-                };
-                Token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())), suffix)
-            }
-            LitKind::Float(symbol, ty) => {
-                Token::Literal(token::Lit::Float(symbol), Some(Symbol::intern(ty.ty_to_string())))
-            }
-            LitKind::FloatUnsuffixed(symbol) => Token::Literal(token::Lit::Float(symbol), None),
-            LitKind::Bool(value) => Token::Ident(Ident::with_empty_ctxt(Symbol::intern(if value {
-                "true"
-            } else {
-                "false"
-            })), false),
-            LitKind::Err(val) => Token::Literal(token::Lit::Err(val), None),
-        }
-    }
-
-    fn from_token(token: Token) -> Option<LitKind> {
-        match token {
-            Token::Ident(ident, false) if ident.name == "true" => Some(LitKind::Bool(true)),
-            Token::Ident(ident, false) if ident.name == "false" => Some(LitKind::Bool(false)),
-            Token::Interpolated(nt) => match *nt {
-                token::NtExpr(ref v) | token::NtLiteral(ref v) => match v.node {
-                    ExprKind::Lit(ref lit) => Some(lit.node.clone()),
-                    _ => None,
-                },
-                _ => None,
-            },
-            Token::Literal(lit, suf) => {
-                let (suffix_illegal, result) = parse::lit_token(lit, suf, None);
-                if suffix_illegal && suf.is_some() {
-                    return None;
-                }
-                result
-            }
-            _ => None,
-        }
-    }
-}
-
 pub trait HasAttrs: Sized {
     fn attrs(&self) -> &[ast::Attribute];
     fn visit_attrs<F: FnOnce(&mut Vec<ast::Attribute>)>(&mut self, f: F);
index 18173628a2602f922cf89d8b0cb89ed675ffc295..c82936afa3d9f0f96d815a36eddb05c326901a2c 100644 (file)
@@ -12,6 +12,7 @@
 use crate::mut_visit::*;
 use crate::parse::{token, ParseSess};
 use crate::ptr::P;
+use crate::symbol::sym;
 use crate::util::map_in_place::MapInPlace;
 
 use errors::Applicability;
@@ -90,7 +91,7 @@ pub fn process_cfg_attrs<T: HasAttrs>(&mut self, node: &mut T) {
     /// is in the original source file. Gives a compiler error if the syntax of
     /// the attribute is incorrect.
     fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
-        if !attr.check_name("cfg_attr") {
+        if !attr.check_name(sym::cfg_attr) {
             return vec![attr];
         }
 
@@ -205,7 +206,7 @@ fn visit_expr_attrs(&mut self, attrs: &[ast::Attribute]) {
     pub fn maybe_emit_expr_attr_err(&self, attr: &ast::Attribute) {
         if !self.features.map(|features| features.stmt_expr_attributes).unwrap_or(true) {
             let mut err = feature_err(self.sess,
-                                      "stmt_expr_attributes",
+                                      sym::stmt_expr_attributes,
                                       attr.span,
                                       GateIssue::Language,
                                       EXPLAIN_STMT_ATTR_SYNTAX);
@@ -285,9 +286,9 @@ pub fn configure_pat(&mut self, pat: &mut P<ast::Pat>) {
     /// See issue #51279.
     pub fn disallow_cfg_on_generic_param(&mut self, param: &ast::GenericParam) {
         for attr in param.attrs() {
-            let offending_attr = if attr.check_name("cfg") {
+            let offending_attr = if attr.check_name(sym::cfg) {
                 "cfg"
-            } else if attr.check_name("cfg_attr") {
+            } else if attr.check_name(sym::cfg_attr) {
                 "cfg_attr"
             } else {
                 continue;
@@ -350,5 +351,5 @@ fn visit_pat(&mut self, pat: &mut P<ast::Pat>) {
 }
 
 fn is_cfg(attr: &ast::Attribute) -> bool {
-    attr.check_name("cfg")
+    attr.check_name(sym::cfg)
 }
index 09e26e29d86a81857a2092fa1b3407ae0b876711..0b6cf30bd27d248207397ef3338ae9f62e4faff9 100644 (file)
@@ -1,5 +1,6 @@
 use crate::attr;
 use crate::ast::{Item, ItemKind};
+use crate::symbol::sym;
 
 pub enum EntryPointType {
     None,
@@ -14,11 +15,11 @@ pub enum EntryPointType {
 pub fn entry_point_type(item: &Item, depth: usize) -> EntryPointType {
     match item.node {
         ItemKind::Fn(..) => {
-            if attr::contains_name(&item.attrs, "start") {
+            if attr::contains_name(&item.attrs, sym::start) {
                 EntryPointType::Start
-            } else if attr::contains_name(&item.attrs, "main") {
+            } else if attr::contains_name(&item.attrs, sym::main) {
                 EntryPointType::MainAttr
-            } else if item.ident.name == "main" {
+            } else if item.ident.name == sym::main {
                 if depth == 1 {
                     // This is a top-level function so can be 'main'
                     EntryPointType::MainNamed
index cc19acb61adc2e2763a703a867336d5a6250704e..0a88d2f8824d3f3d34ad908dff6c9ada3a299201 100644 (file)
@@ -10,7 +10,7 @@
 use crate::parse::{self, parser, DirectoryOwnership};
 use crate::parse::token;
 use crate::ptr::P;
-use crate::symbol::{keywords, Ident, Symbol};
+use crate::symbol::{keywords, Ident, Symbol, sym};
 use crate::ThinVec;
 use crate::tokenstream::{self, TokenStream};
 
@@ -871,7 +871,7 @@ pub fn expansion_cause(&self) -> Option<Span> {
         let mut last_macro = None;
         loop {
             if ctxt.outer().expn_info().map_or(None, |info| {
-                if info.format.name() == "include" {
+                if info.format.name() == sym::include {
                     // Stop going up the backtrace once include! is encountered
                     return None;
                 }
index 40dd187ed28a7e5560ee7eeb26e0a226dc16bfd9..d24106f697e19f1470fd4a6adecfad08c73191b6 100644 (file)
@@ -697,8 +697,9 @@ fn expr_struct_ident(&self, span: Span,
         self.expr_struct(span, self.path_ident(span, id), fields)
     }
 
-    fn expr_lit(&self, sp: Span, lit: ast::LitKind) -> P<ast::Expr> {
-        self.expr(sp, ast::ExprKind::Lit(respan(sp, lit)))
+    fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P<ast::Expr> {
+        let lit = ast::Lit::from_lit_kind(lit_kind, span);
+        self.expr(span, ast::ExprKind::Lit(lit))
     }
     fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr> {
         self.expr_lit(span, ast::LitKind::Int(i as u128,
@@ -1164,10 +1165,10 @@ fn meta_list(&self, sp: Span, name: ast::Name, mis: Vec<ast::NestedMetaItem>)
         attr::mk_list_item(sp, Ident::with_empty_ctxt(name).with_span_pos(sp), mis)
     }
 
-    fn meta_name_value(&self, sp: Span, name: ast::Name, value: ast::LitKind)
+    fn meta_name_value(&self, span: Span, name: ast::Name, lit_kind: ast::LitKind)
                        -> ast::MetaItem {
-        attr::mk_name_value_item(sp, Ident::with_empty_ctxt(name).with_span_pos(sp),
-                                 respan(sp, value))
+        attr::mk_name_value_item(span, Ident::with_empty_ctxt(name).with_span_pos(span),
+                                 lit_kind, span)
     }
 
     fn item_use(&self, sp: Span,
index 6df369133d01dd99630a838bc672ed6e3abe2000..a24e09f127eaeef07012848accc355eb46d3951f 100644 (file)
@@ -4,7 +4,7 @@
 use crate::ext::base::ExtCtxt;
 use crate::ext::build::AstBuilder;
 use crate::parse::parser::PathStyle;
-use crate::symbol::Symbol;
+use crate::symbol::{Symbol, sym};
 
 use syntax_pos::Span;
 
@@ -13,7 +13,7 @@
 pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) -> Vec<ast::Path> {
     let mut result = Vec::new();
     attrs.retain(|attr| {
-        if attr.path != "derive" {
+        if attr.path != sym::derive {
             return true;
         }
         if !attr.is_meta_item_list() {
index 82358679c0e824281559710d016b9a29b12db51d..a286fd83e3c208ff8b5d802e816f188006241e48 100644 (file)
@@ -14,7 +14,7 @@
 use crate::parse::parser::Parser;
 use crate::ptr::P;
 use crate::symbol::Symbol;
-use crate::symbol::keywords;
+use crate::symbol::{keywords, sym};
 use crate::tokenstream::{TokenStream, TokenTree};
 use crate::visit::{self, Visitor};
 use crate::util::map_in_place::MapInPlace;
@@ -356,7 +356,7 @@ fn expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragment {
                     self.collect_invocations(fragment, &[])
                 } else if let InvocationKind::Attr { attr: None, traits, item, .. } = invoc.kind {
                     if !item.derive_allowed() {
-                        let attr = attr::find_by_name(item.attrs(), "derive")
+                        let attr = attr::find_by_name(item.attrs(), sym::derive)
                             .expect("`derive` attribute should exist");
                         let span = attr.span;
                         let mut err = self.cx.mut_span_err(span,
@@ -376,7 +376,7 @@ fn expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragment {
                     }
 
                     let mut item = self.fully_configure(item);
-                    item.visit_attrs(|attrs| attrs.retain(|a| a.path != "derive"));
+                    item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive));
                     let mut item_with_markers = item.clone();
                     add_derived_markers(&mut self.cx, item.span(), &traits, &mut item_with_markers);
                     let derives = derives.entry(invoc.expansion_data.mark).or_default();
@@ -510,7 +510,7 @@ fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> Option<A
         if invoc.fragment_kind == AstFragmentKind::ForeignItems &&
            !self.cx.ecfg.macros_in_extern_enabled() {
             if let SyntaxExtension::NonMacroAttr { .. } = *ext {} else {
-                emit_feature_err(&self.cx.parse_sess, "macros_in_extern",
+                emit_feature_err(&self.cx.parse_sess, sym::macros_in_extern,
                                  invoc.span(), GateIssue::Language,
                                  "macro invocations in `extern {}` blocks are experimental");
             }
@@ -636,7 +636,7 @@ fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
             Annotatable::Item(ref item) => {
                 match item.node {
                     ItemKind::Mod(_) if self.cx.ecfg.proc_macro_hygiene() => return,
-                    ItemKind::Mod(_) => ("modules", "proc_macro_hygiene"),
+                    ItemKind::Mod(_) => ("modules", sym::proc_macro_hygiene),
                     _ => return,
                 }
             }
@@ -645,8 +645,8 @@ fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
             Annotatable::ForeignItem(_) => return,
             Annotatable::Stmt(_) |
             Annotatable::Expr(_) if self.cx.ecfg.proc_macro_hygiene() => return,
-            Annotatable::Stmt(_) => ("statements", "proc_macro_hygiene"),
-            Annotatable::Expr(_) => ("expressions", "proc_macro_hygiene"),
+            Annotatable::Stmt(_) => ("statements", sym::proc_macro_hygiene),
+            Annotatable::Expr(_) => ("expressions", sym::proc_macro_hygiene),
         };
         emit_feature_err(
             self.cx.parse_sess,
@@ -681,7 +681,7 @@ fn visit_item(&mut self, i: &'ast ast::Item) {
                 if let ast::ItemKind::MacroDef(_) = i.node {
                     emit_feature_err(
                         self.parse_sess,
-                        "proc_macro_hygiene",
+                        sym::proc_macro_hygiene,
                         self.span,
                         GateIssue::Language,
                         "procedural macros cannot expand to macro definitions",
@@ -724,13 +724,13 @@ fn expand_bang_invoc(&mut self,
                 // don't stability-check macros in the same crate
                 // (the only time this is null is for syntax extensions registered as macros)
                 if def_site_span.map_or(false, |def_span| !crate_span.contains(def_span))
-                    && !span.allows_unstable(&feature.as_str())
+                    && !span.allows_unstable(feature)
                     && this.cx.ecfg.features.map_or(true, |feats| {
                     // macro features will count as lib features
                     !feats.declared_lib_features.iter().any(|&(feat, _)| feat == feature)
                 }) {
                     let explain = format!("macro {}! is unstable", path);
-                    emit_feature_err(this.cx.parse_sess, &*feature.as_str(), span,
+                    emit_feature_err(this.cx.parse_sess, feature, span,
                                      GateIssue::Library(Some(issue)), &explain);
                     this.cx.trace_macros_diag();
                 }
@@ -885,7 +885,7 @@ fn gate_proc_macro_expansion_kind(&self, span: Span, kind: AstFragmentKind) {
         }
         emit_feature_err(
             self.cx.parse_sess,
-            "proc_macro_hygiene",
+            sym::proc_macro_hygiene,
             span,
             GateIssue::Language,
             &format!("procedural macros cannot be expanded to {}", kind),
@@ -1109,7 +1109,7 @@ fn find_attr_invoc(&self, attrs: &mut Vec<ast::Attribute>, after_derive: &mut bo
                        -> Option<ast::Attribute> {
         let attr = attrs.iter()
                         .position(|a| {
-                            if a.path == "derive" {
+                            if a.path == sym::derive {
                                 *after_derive = true;
                             }
                             !attr::is_known(a) && !is_builtin_attr(a)
@@ -1117,8 +1117,8 @@ fn find_attr_invoc(&self, attrs: &mut Vec<ast::Attribute>, after_derive: &mut bo
                         .map(|i| attrs.remove(i));
         if let Some(attr) = &attr {
             if !self.cx.ecfg.enable_custom_inner_attributes() &&
-               attr.style == ast::AttrStyle::Inner && attr.path != "test" {
-                emit_feature_err(&self.cx.parse_sess, "custom_inner_attributes",
+               attr.style == ast::AttrStyle::Inner && attr.path != sym::test {
+                emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes,
                                  attr.span, GateIssue::Language,
                                  "non-builtin inner attributes are unstable");
             }
@@ -1167,7 +1167,7 @@ fn check_attributes(&mut self, attrs: &[ast::Attribute]) {
             self.check_attribute_inner(attr, features);
 
             // macros are expanded before any lint passes so this warning has to be hardcoded
-            if attr.path == "derive" {
+            if attr.path == sym::derive {
                 self.cx.struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations")
                     .note("this may become a hard error in a future release")
                     .emit();
@@ -1352,7 +1352,7 @@ fn visit_block(&mut self, block: &mut P<Block>) {
                 let inline_module = item.span.contains(inner) || inner.is_dummy();
 
                 if inline_module {
-                    if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, "path") {
+                    if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, sym::path) {
                         self.cx.current_expansion.directory_ownership =
                             DirectoryOwnership::Owned { relative: None };
                         module.directory.push(&*path.as_str());
@@ -1485,19 +1485,19 @@ fn visit_generic_param(&mut self, param: &mut ast::GenericParam) {
     fn visit_attribute(&mut self, at: &mut ast::Attribute) {
         // turn `#[doc(include="filename")]` attributes into `#[doc(include(file="filename",
         // contents="file contents")]` attributes
-        if !at.check_name("doc") {
+        if !at.check_name(sym::doc) {
             return noop_visit_attribute(at, self);
         }
 
         if let Some(list) = at.meta_item_list() {
-            if !list.iter().any(|it| it.check_name("include")) {
+            if !list.iter().any(|it| it.check_name(sym::include)) {
                 return noop_visit_attribute(at, self);
             }
 
             let mut items = vec![];
 
             for mut it in list {
-                if !it.check_name("include") {
+                if !it.check_name(sym::include) {
                     items.push({ noop_visit_meta_list_item(&mut it, self); it });
                     continue;
                 }
index 549de1628eb550e5979d72767cc150a740e82ced..e1cb90d9e71d652033ad2bb4c250516d0e34b055 100644 (file)
@@ -4,7 +4,7 @@
 use crate::parse::{self, token, DirectoryOwnership};
 use crate::print::pprust;
 use crate::ptr::P;
-use crate::symbol::Symbol;
+use crate::symbol::{Symbol, sym};
 use crate::tokenstream;
 
 use smallvec::SmallVec;
@@ -44,7 +44,7 @@ pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTr
 /* __rust_unstable_column!(): expands to the current column number */
 pub fn expand_column_gated(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
                   -> Box<dyn base::MacResult+'static> {
-    if sp.allows_unstable("__rust_unstable_column") {
+    if sp.allows_unstable(sym::__rust_unstable_column) {
         expand_column(cx, sp, tts)
     } else {
         cx.span_fatal(sp, "the __rust_unstable_column macro is unstable");
index a53cc2fe66173ecdce8ce9f25c3eea713f31efc5..06651750de74198c31ce8f66ea5cd88b3ea85969 100644 (file)
@@ -13,7 +13,7 @@
 use crate::parse::parser::Parser;
 use crate::parse::token::{self, NtTT};
 use crate::parse::token::Token::*;
-use crate::symbol::Symbol;
+use crate::symbol::{Symbol, keywords, sym};
 use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
 
 use errors::FatalError;
@@ -376,7 +376,7 @@ pub fn compile(
     });
 
     if body.legacy {
-        let allow_internal_unstable = attr::find_by_name(&def.attrs, "allow_internal_unstable")
+        let allow_internal_unstable = attr::find_by_name(&def.attrs, sym::allow_internal_unstable)
             .map(|attr| attr
                 .meta_item_list()
                 .map(|list| list.iter()
@@ -399,11 +399,11 @@ pub fn compile(
                     vec![Symbol::intern("allow_internal_unstable_backcompat_hack")].into()
                 })
             );
-        let allow_internal_unsafe = attr::contains_name(&def.attrs, "allow_internal_unsafe");
+        let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe);
         let mut local_inner_macros = false;
-        if let Some(macro_export) = attr::find_by_name(&def.attrs, "macro_export") {
+        if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) {
             if let Some(l) = macro_export.meta_item_list() {
-                local_inner_macros = attr::list_contains_name(&l, "local_inner_macros");
+                local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
             }
         }
 
@@ -426,7 +426,7 @@ pub fn compile(
             edition,
         }
     } else {
-        let is_transparent = attr::contains_name(&def.attrs, "rustc_transparent_macro");
+        let is_transparent = attr::contains_name(&def.attrs, sym::rustc_transparent_macro);
 
         SyntaxExtension::DeclMacro {
             expander,
@@ -467,7 +467,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool {
             TokenTree::Sequence(span, ref seq) => {
                 if seq.separator.is_none() && seq.tts.iter().all(|seq_tt| {
                     match *seq_tt {
-                        TokenTree::MetaVarDecl(_, _, id) => id.name == "vis",
+                        TokenTree::MetaVarDecl(_, _, id) => id.name == sym::vis,
                         TokenTree::Sequence(_, ref sub_seq) =>
                             sub_seq.op == quoted::KleeneOp::ZeroOrMore
                             || sub_seq.op == quoted::KleeneOp::ZeroOrOne,
@@ -1046,7 +1046,8 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> IsInFollow {
                 match *tok {
                     TokenTree::Token(_, ref tok) => match *tok {
                         FatArrow | Comma | Eq | BinOp(token::Or) => IsInFollow::Yes,
-                        Ident(i, false) if i.name == "if" || i.name == "in" => IsInFollow::Yes,
+                        Ident(i, false) if i.name == keywords::If.name() ||
+                                           i.name == keywords::In.name() => IsInFollow::Yes,
                         _ => IsInFollow::No(tokens),
                     },
                     _ => IsInFollow::No(tokens),
@@ -1063,10 +1064,12 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> IsInFollow {
                         OpenDelim(token::DelimToken::Bracket) |
                         Comma | FatArrow | Colon | Eq | Gt | BinOp(token::Shr) | Semi |
                         BinOp(token::Or) => IsInFollow::Yes,
-                        Ident(i, false) if i.name == "as" || i.name == "where" => IsInFollow::Yes,
+                        Ident(i, false) if i.name == keywords::As.name() ||
+                                           i.name == keywords::Where.name() => IsInFollow::Yes,
                         _ => IsInFollow::No(tokens),
                     },
-                    TokenTree::MetaVarDecl(_, _, frag) if frag.name == "block" => IsInFollow::Yes,
+                    TokenTree::MetaVarDecl(_, _, frag) if frag.name == sym::block =>
+                        IsInFollow::Yes,
                     _ => IsInFollow::No(tokens),
                 }
             },
@@ -1089,16 +1092,18 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> IsInFollow {
                 match *tok {
                     TokenTree::Token(_, ref tok) => match *tok {
                         Comma => IsInFollow::Yes,
-                        Ident(i, is_raw) if is_raw || i.name != "priv" => IsInFollow::Yes,
+                        Ident(i, is_raw) if is_raw || i.name != keywords::Priv.name() =>
+                            IsInFollow::Yes,
                         ref tok => if tok.can_begin_type() {
                             IsInFollow::Yes
                         } else {
                             IsInFollow::No(tokens)
                         }
                     },
-                    TokenTree::MetaVarDecl(_, _, frag) if frag.name == "ident"
-                                                       || frag.name == "ty"
-                                                       || frag.name == "path" => IsInFollow::Yes,
+                    TokenTree::MetaVarDecl(_, _, frag) if frag.name == sym::ident
+                                                       || frag.name == sym::ty
+                                                       || frag.name == sym::path =>
+                        IsInFollow::Yes,
                     _ => IsInFollow::No(tokens),
                 }
             },
index c3bad3aba184b06bfb16ab58ccdf5be865866c6c..8a066f3f4a093a82c2fd96c84727d31a166520c3 100644 (file)
 use crate::edition::{ALL_EDITIONS, Edition};
 use crate::visit::{self, FnKind, Visitor};
 use crate::parse::{token, ParseSess};
-use crate::symbol::Symbol;
+use crate::symbol::{Symbol, keywords, sym};
 use crate::tokenstream::TokenTree;
 
 use errors::{DiagnosticBuilder, Handler};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_target::spec::abi::Abi;
-use syntax_pos::{Span, DUMMY_SP, symbols};
+use syntax_pos::{Span, DUMMY_SP};
 use log::debug;
 use lazy_static::lazy_static;
 
@@ -48,8 +48,8 @@ macro_rules! declare_features {
         /// Represents active features that are currently being implemented or
         /// currently being considered for addition/removal.
         const ACTIVE_FEATURES:
-            &[(&str, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] =
-            &[$((stringify!($feature), $ver, $issue, $edition, set!($feature))),+];
+            &[(Symbol, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] =
+            &[$((sym::$feature, $ver, $issue, $edition, set!($feature))),+];
 
         /// A set of features to be used by later passes.
         #[derive(Clone)]
@@ -80,22 +80,22 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
 
     ($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => {
         /// Represents unstable features which have since been removed (it was once Active)
-        const REMOVED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
-            $((stringify!($feature), $ver, $issue, $reason)),+
+        const REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+            $((sym::$feature, $ver, $issue, $reason)),+
         ];
     };
 
     ($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
         /// Represents stable features which have since been removed (it was once Accepted)
-        const STABLE_REMOVED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
-            $((stringify!($feature), $ver, $issue, None)),+
+        const STABLE_REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+            $((sym::$feature, $ver, $issue, None)),+
         ];
     };
 
     ($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
         /// Those language feature has since been Accepted (it was once Active)
-        const ACCEPTED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
-            $((stringify!($feature), $ver, $issue, None)),+
+        const ACCEPTED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+            $((sym::$feature, $ver, $issue, None)),+
         ];
     }
 }
@@ -562,9 +562,10 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
 // Some features are known to be incomplete and using them is likely to have
 // unanticipated results, such as compiler crashes. We warn the user about these
 // to alert them.
-const INCOMPLETE_FEATURES: &[&str] = &[
-    "generic_associated_types",
-    "const_generics"
+const INCOMPLETE_FEATURES: &[Symbol] = &[
+    sym::impl_trait_in_bindings,
+    sym::generic_associated_types,
+    sym::const_generics
 ];
 
 declare_features! (
@@ -860,7 +861,7 @@ pub enum AttributeType {
 pub enum AttributeGate {
     /// Is gated by a given feature gate, reason
     /// and function to check if enabled
-    Gated(Stability, &'static str, &'static str, fn(&Features) -> bool),
+    Gated(Stability, Symbol, &'static str, fn(&Features) -> bool),
 
     /// Ungated attribute, can be used on all release channels
     Ungated,
@@ -962,232 +963,232 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
     // Normal attributes
 
     (
-        symbols::warn,
+        sym::warn,
         Normal,
         template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
         Ungated
     ),
     (
-        symbols::allow,
+        sym::allow,
         Normal,
         template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
         Ungated
     ),
     (
-        symbols::forbid,
+        sym::forbid,
         Normal,
         template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
         Ungated
     ),
     (
-        symbols::deny,
+        sym::deny,
         Normal,
         template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
         Ungated
     ),
 
-    (symbols::macro_use, Normal, template!(Word, List: "name1, name2, ..."), Ungated),
-    (symbols::macro_export, Normal, template!(Word, List: "local_inner_macros"), Ungated),
-    (symbols::plugin_registrar, Normal, template!(Word), Ungated),
-
-    (symbols::cfg, Normal, template!(List: "predicate"), Ungated),
-    (symbols::cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), Ungated),
-    (symbols::main, Normal, template!(Word), Ungated),
-    (symbols::start, Normal, template!(Word), Ungated),
-    (symbols::repr, Normal, template!(List: "C, packed, ..."), Ungated),
-    (symbols::path, Normal, template!(NameValueStr: "file"), Ungated),
-    (symbols::automatically_derived, Normal, template!(Word), Ungated),
-    (symbols::no_mangle, Normal, template!(Word), Ungated),
-    (symbols::no_link, Normal, template!(Word), Ungated),
-    (symbols::derive, Normal, template!(List: "Trait1, Trait2, ..."), Ungated),
+    (sym::macro_use, Normal, template!(Word, List: "name1, name2, ..."), Ungated),
+    (sym::macro_export, Normal, template!(Word, List: "local_inner_macros"), Ungated),
+    (sym::plugin_registrar, Normal, template!(Word), Ungated),
+
+    (sym::cfg, Normal, template!(List: "predicate"), Ungated),
+    (sym::cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), Ungated),
+    (sym::main, Normal, template!(Word), Ungated),
+    (sym::start, Normal, template!(Word), Ungated),
+    (sym::repr, Normal, template!(List: "C, packed, ..."), Ungated),
+    (sym::path, Normal, template!(NameValueStr: "file"), Ungated),
+    (sym::automatically_derived, Normal, template!(Word), Ungated),
+    (sym::no_mangle, Normal, template!(Word), Ungated),
+    (sym::no_link, Normal, template!(Word), Ungated),
+    (sym::derive, Normal, template!(List: "Trait1, Trait2, ..."), Ungated),
     (
-        symbols::should_panic,
+        sym::should_panic,
         Normal,
         template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"),
         Ungated
     ),
-    (symbols::ignore, Normal, template!(Word, NameValueStr: "reason"), Ungated),
-    (symbols::no_implicit_prelude, Normal, template!(Word), Ungated),
-    (symbols::reexport_test_harness_main, Normal, template!(NameValueStr: "name"), Ungated),
-    (symbols::link_args, Normal, template!(NameValueStr: "args"), Gated(Stability::Unstable,
-                                "link_args",
+    (sym::ignore, Normal, template!(Word, NameValueStr: "reason"), Ungated),
+    (sym::no_implicit_prelude, Normal, template!(Word), Ungated),
+    (sym::reexport_test_harness_main, Normal, template!(NameValueStr: "name"), Ungated),
+    (sym::link_args, Normal, template!(NameValueStr: "args"), Gated(Stability::Unstable,
+                                sym::link_args,
                                 "the `link_args` attribute is experimental and not \
                                 portable across platforms, it is recommended to \
                                 use `#[link(name = \"foo\")] instead",
                                 cfg_fn!(link_args))),
-    (symbols::macro_escape, Normal, template!(Word), Ungated),
+    (sym::macro_escape, Normal, template!(Word), Ungated),
 
     // RFC #1445.
-    (symbols::structural_match, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "structural_match",
+    (sym::structural_match, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::structural_match,
                                             "the semantics of constant patterns is \
                                             not yet settled",
                                             cfg_fn!(structural_match))),
 
     // RFC #2008
-    (symbols::non_exhaustive, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        "non_exhaustive",
+    (sym::non_exhaustive, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                        sym::non_exhaustive,
                                         "non exhaustive is an experimental feature",
                                         cfg_fn!(non_exhaustive))),
 
     // RFC #1268
-    (symbols::marker, Normal, template!(Word), Gated(Stability::Unstable,
-                            "marker_trait_attr",
+    (sym::marker, Normal, template!(Word), Gated(Stability::Unstable,
+                            sym::marker_trait_attr,
                             "marker traits is an experimental feature",
                             cfg_fn!(marker_trait_attr))),
 
-    (symbols::plugin, CrateLevel, template!(List: "name|name(args)"), Gated(Stability::Unstable,
-                                "plugin",
+    (sym::plugin, CrateLevel, template!(List: "name|name(args)"), Gated(Stability::Unstable,
+                                sym::plugin,
                                 "compiler plugins are experimental \
                                 and possibly buggy",
                                 cfg_fn!(plugin))),
 
-    (symbols::no_std, CrateLevel, template!(Word), Ungated),
-    (symbols::no_core, CrateLevel, template!(Word), Gated(Stability::Unstable,
-                                "no_core",
+    (sym::no_std, CrateLevel, template!(Word), Ungated),
+    (sym::no_core, CrateLevel, template!(Word), Gated(Stability::Unstable,
+                                sym::no_core,
                                 "no_core is experimental",
                                 cfg_fn!(no_core))),
-    (symbols::lang, Normal, template!(NameValueStr: "name"), Gated(Stability::Unstable,
-                        "lang_items",
+    (sym::lang, Normal, template!(NameValueStr: "name"), Gated(Stability::Unstable,
+                        sym::lang_items,
                         "language items are subject to change",
                         cfg_fn!(lang_items))),
-    (symbols::linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
+    (sym::linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
                                 Gated(Stability::Unstable,
-                                "linkage",
+                                sym::linkage,
                                 "the `linkage` attribute is experimental \
                                     and not portable across platforms",
                                 cfg_fn!(linkage))),
-    (symbols::thread_local, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        "thread_local",
+    (sym::thread_local, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                        sym::thread_local,
                                         "`#[thread_local]` is an experimental feature, and does \
                                          not currently handle destructors",
                                         cfg_fn!(thread_local))),
 
-    (symbols::rustc_on_unimplemented, Whitelisted, template!(List:
+    (sym::rustc_on_unimplemented, Whitelisted, template!(List:
                         r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
                         NameValueStr: "message"),
                                             Gated(Stability::Unstable,
-                                            "on_unimplemented",
+                                            sym::on_unimplemented,
                                             "the `#[rustc_on_unimplemented]` attribute \
                                             is an experimental feature",
                                             cfg_fn!(on_unimplemented))),
-    (symbols::rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
+    (sym::rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
                                             Gated(Stability::Unstable,
-                                            "rustc_const_unstable",
+                                            sym::rustc_const_unstable,
                                             "the `#[rustc_const_unstable]` attribute \
                                             is an internal feature",
                                             cfg_fn!(rustc_const_unstable))),
-    (symbols::global_allocator, Normal, template!(Word), Ungated),
-    (symbols::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "allocator_internals",
+    (sym::global_allocator, Normal, template!(Word), Ungated),
+    (sym::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::allocator_internals,
                                             "the `#[default_lib_allocator]` \
                                             attribute is an experimental feature",
                                             cfg_fn!(allocator_internals))),
-    (symbols::needs_allocator, Normal, template!(Word), Gated(Stability::Unstable,
-                                    "allocator_internals",
+    (sym::needs_allocator, Normal, template!(Word), Gated(Stability::Unstable,
+                                    sym::allocator_internals,
                                     "the `#[needs_allocator]` \
                                     attribute is an experimental \
                                     feature",
                                     cfg_fn!(allocator_internals))),
-    (symbols::panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        "panic_runtime",
+    (sym::panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                        sym::panic_runtime,
                                         "the `#[panic_runtime]` attribute is \
                                         an experimental feature",
                                         cfg_fn!(panic_runtime))),
-    (symbols::needs_panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "needs_panic_runtime",
+    (sym::needs_panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::needs_panic_runtime,
                                             "the `#[needs_panic_runtime]` \
                                                 attribute is an experimental \
                                                 feature",
                                             cfg_fn!(needs_panic_runtime))),
-    (symbols::rustc_outlives, Normal, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+    (sym::rustc_outlives, Normal, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
                                     "the `#[rustc_outlives]` attribute \
                                     is just used for rustc unit tests \
                                     and will never be stable",
                                     cfg_fn!(rustc_attrs))),
-    (symbols::rustc_variance, Normal, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+    (sym::rustc_variance, Normal, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
                                     "the `#[rustc_variance]` attribute \
                                     is just used for rustc unit tests \
                                     and will never be stable",
                                     cfg_fn!(rustc_attrs))),
-    (symbols::rustc_layout, Normal, template!(List: "field1, field2, ..."),
+    (sym::rustc_layout, Normal, template!(List: "field1, field2, ..."),
     Gated(Stability::Unstable,
-        "rustc_attrs",
+        sym::rustc_attrs,
         "the `#[rustc_layout]` attribute \
             is just used for rustc unit tests \
             and will never be stable",
         cfg_fn!(rustc_attrs))),
-    (symbols::rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"),
+    (sym::rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"),
     Gated(Stability::Unstable,
-        "rustc_attrs",
+        sym::rustc_attrs,
         "the `#[rustc_layout_scalar_valid_range_start]` attribute \
             is just used to enable niche optimizations in libcore \
             and will never be stable",
         cfg_fn!(rustc_attrs))),
-    (symbols::rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"),
+    (sym::rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"),
     Gated(Stability::Unstable,
-        "rustc_attrs",
+        sym::rustc_attrs,
         "the `#[rustc_layout_scalar_valid_range_end]` attribute \
             is just used to enable niche optimizations in libcore \
             and will never be stable",
         cfg_fn!(rustc_attrs))),
-    (symbols::rustc_regions, Normal, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+    (sym::rustc_regions, Normal, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
                                     "the `#[rustc_regions]` attribute \
                                     is just used for rustc unit tests \
                                     and will never be stable",
                                     cfg_fn!(rustc_attrs))),
-    (symbols::rustc_error, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+    (sym::rustc_error, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
                                     "the `#[rustc_error]` attribute \
                                         is just used for rustc unit tests \
                                         and will never be stable",
                                     cfg_fn!(rustc_attrs))),
-    (symbols::rustc_dump_user_substs, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+    (sym::rustc_dump_user_substs, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
                                     "this attribute \
                                         is just used for rustc unit tests \
                                         and will never be stable",
                                     cfg_fn!(rustc_attrs))),
-    (symbols::rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode"),
+    (sym::rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode"),
                                                 Gated(Stability::Unstable,
-                                                "rustc_attrs",
+                                                sym::rustc_attrs,
                                                 "the `#[rustc_if_this_changed]` attribute \
                                                 is just used for rustc unit tests \
                                                 and will never be stable",
                                                 cfg_fn!(rustc_attrs))),
-    (symbols::rustc_then_this_would_need, Whitelisted, template!(List: "DepNode"),
+    (sym::rustc_then_this_would_need, Whitelisted, template!(List: "DepNode"),
                                                     Gated(Stability::Unstable,
-                                                    "rustc_attrs",
+                                                    sym::rustc_attrs,
                                                     "the `#[rustc_if_this_changed]` attribute \
                                                     is just used for rustc unit tests \
                                                     and will never be stable",
                                                     cfg_fn!(rustc_attrs))),
-    (symbols::rustc_dirty, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
+    (sym::rustc_dirty, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
                                                     /*opt*/ except = "...""#),
                                     Gated(Stability::Unstable,
-                                    "rustc_attrs",
+                                    sym::rustc_attrs,
                                     "the `#[rustc_dirty]` attribute \
                                         is just used for rustc unit tests \
                                         and will never be stable",
                                     cfg_fn!(rustc_attrs))),
-    (symbols::rustc_clean, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
+    (sym::rustc_clean, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
                                                     /*opt*/ except = "...""#),
                                     Gated(Stability::Unstable,
-                                    "rustc_attrs",
+                                    sym::rustc_attrs,
                                     "the `#[rustc_clean]` attribute \
                                         is just used for rustc unit tests \
                                         and will never be stable",
                                     cfg_fn!(rustc_attrs))),
     (
-        symbols::rustc_partition_reused,
+        sym::rustc_partition_reused,
         Whitelisted,
         template!(List: r#"cfg = "...", module = "...""#),
         Gated(
             Stability::Unstable,
-            "rustc_attrs",
+            sym::rustc_attrs,
             "this attribute \
             is just used for rustc unit tests \
             and will never be stable",
@@ -1195,53 +1196,53 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
         )
     ),
     (
-        symbols::rustc_partition_codegened,
+        sym::rustc_partition_codegened,
         Whitelisted,
         template!(List: r#"cfg = "...", module = "...""#),
         Gated(
             Stability::Unstable,
-            "rustc_attrs",
+            sym::rustc_attrs,
             "this attribute \
             is just used for rustc unit tests \
             and will never be stable",
             cfg_fn!(rustc_attrs),
         )
     ),
-    (symbols::rustc_expected_cgu_reuse, Whitelisted, template!(List: r#"cfg = "...", module = "...",
+    (sym::rustc_expected_cgu_reuse, Whitelisted, template!(List: r#"cfg = "...", module = "...",
                                                             kind = "...""#),
                                                     Gated(Stability::Unstable,
-                                                    "rustc_attrs",
+                                                    sym::rustc_attrs,
                                                     "this attribute \
                                                     is just used for rustc unit tests \
                                                     and will never be stable",
                                                     cfg_fn!(rustc_attrs))),
-    (symbols::rustc_synthetic, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    "rustc_attrs",
+    (sym::rustc_synthetic, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                    sym::rustc_attrs,
                                                     "this attribute \
                                                     is just used for rustc unit tests \
                                                     and will never be stable",
                                                     cfg_fn!(rustc_attrs))),
-    (symbols::rustc_symbol_name, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "rustc_attrs",
+    (sym::rustc_symbol_name, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::rustc_attrs,
                                             "internal rustc attributes will never be stable",
                                             cfg_fn!(rustc_attrs))),
-    (symbols::rustc_def_path, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        "rustc_attrs",
+    (sym::rustc_def_path, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                        sym::rustc_attrs,
                                         "internal rustc attributes will never be stable",
                                         cfg_fn!(rustc_attrs))),
-    (symbols::rustc_mir, Whitelisted, template!(List: "arg1, arg2, ..."), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+    (sym::rustc_mir, Whitelisted, template!(List: "arg1, arg2, ..."), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
                                     "the `#[rustc_mir]` attribute \
                                     is just used for rustc unit tests \
                                     and will never be stable",
                                     cfg_fn!(rustc_attrs))),
     (
-        symbols::rustc_inherit_overflow_checks,
+        sym::rustc_inherit_overflow_checks,
         Whitelisted,
         template!(Word),
         Gated(
             Stability::Unstable,
-            "rustc_attrs",
+            sym::rustc_attrs,
             "the `#[rustc_inherit_overflow_checks]` \
             attribute is just used to control \
             overflow checking behavior of several \
@@ -1251,71 +1252,71 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
         )
     ),
 
-    (symbols::rustc_dump_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    "rustc_attrs",
+    (sym::rustc_dump_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                    sym::rustc_attrs,
                                                     "the `#[rustc_dump_program_clauses]` \
                                                     attribute is just used for rustc unit \
                                                     tests and will never be stable",
                                                     cfg_fn!(rustc_attrs))),
-    (symbols::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+    (sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
                                     "the `#[rustc_test_marker]` attribute \
                                     is used internally to track tests",
                                     cfg_fn!(rustc_attrs))),
-    (symbols::rustc_transparent_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                "rustc_attrs",
+    (sym::rustc_transparent_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                sym::rustc_attrs,
                                                 "used internally for testing macro hygiene",
                                                     cfg_fn!(rustc_attrs))),
-    (symbols::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "compiler_builtins",
+    (sym::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::compiler_builtins,
                                             "the `#[compiler_builtins]` attribute is used to \
                                             identify the `compiler_builtins` crate which \
                                             contains compiler-rt intrinsics and will never be \
                                             stable",
                                         cfg_fn!(compiler_builtins))),
-    (symbols::sanitizer_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "sanitizer_runtime",
+    (sym::sanitizer_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::sanitizer_runtime,
                                             "the `#[sanitizer_runtime]` attribute is used to \
                                             identify crates that contain the runtime of a \
                                             sanitizer and will never be stable",
                                             cfg_fn!(sanitizer_runtime))),
-    (symbols::profiler_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            "profiler_runtime",
+    (sym::profiler_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::profiler_runtime,
                                             "the `#[profiler_runtime]` attribute is used to \
                                             identify the `profiler_builtins` crate which \
                                             contains the profiler runtime and will never be \
                                             stable",
                                             cfg_fn!(profiler_runtime))),
 
-    (symbols::allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
+    (sym::allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
                                             Gated(Stability::Unstable,
-                                            "allow_internal_unstable",
+                                            sym::allow_internal_unstable,
                                             EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
                                             cfg_fn!(allow_internal_unstable))),
 
-    (symbols::allow_internal_unsafe, Normal, template!(Word), Gated(Stability::Unstable,
-                                            "allow_internal_unsafe",
+    (sym::allow_internal_unsafe, Normal, template!(Word), Gated(Stability::Unstable,
+                                            sym::allow_internal_unsafe,
                                             EXPLAIN_ALLOW_INTERNAL_UNSAFE,
                                             cfg_fn!(allow_internal_unsafe))),
 
-    (symbols::fundamental, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    "fundamental",
+    (sym::fundamental, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                    sym::fundamental,
                                     "the `#[fundamental]` attribute \
                                         is an experimental feature",
                                     cfg_fn!(fundamental))),
 
-    (symbols::proc_macro_derive, Normal, template!(List: "TraitName, \
+    (sym::proc_macro_derive, Normal, template!(List: "TraitName, \
                                                 /*opt*/ attributes(name1, name2, ...)"),
                                     Ungated),
 
-    (symbols::rustc_copy_clone_marker, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                "rustc_attrs",
+    (sym::rustc_copy_clone_marker, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                sym::rustc_attrs,
                                                 "internal implementation detail",
                                                 cfg_fn!(rustc_attrs))),
 
     // FIXME: #14408 whitelist docs since rustdoc looks at them
     (
-        symbols::doc,
+        sym::doc,
         Whitelisted,
         template!(List: "hidden|inline|...", NameValueStr: "string"),
         Ungated
@@ -1323,94 +1324,94 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
 
     // FIXME: #14406 these are processed in codegen, which happens after the
     // lint pass
-    (symbols::cold, Whitelisted, template!(Word), Ungated),
-    (symbols::naked, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                "naked_functions",
+    (sym::cold, Whitelisted, template!(Word), Ungated),
+    (sym::naked, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                sym::naked_functions,
                                 "the `#[naked]` attribute \
                                 is an experimental feature",
                                 cfg_fn!(naked_functions))),
-    (symbols::ffi_returns_twice, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                "ffi_returns_twice",
+    (sym::ffi_returns_twice, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                sym::ffi_returns_twice,
                                 "the `#[ffi_returns_twice]` attribute \
                                 is an experimental feature",
                                 cfg_fn!(ffi_returns_twice))),
-    (symbols::target_feature, Whitelisted, template!(List: r#"enable = "name""#), Ungated),
-    (symbols::export_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
-    (symbols::inline, Whitelisted, template!(Word, List: "always|never"), Ungated),
-    (symbols::link, Whitelisted, template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...",
+    (sym::target_feature, Whitelisted, template!(List: r#"enable = "name""#), Ungated),
+    (sym::export_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
+    (sym::inline, Whitelisted, template!(Word, List: "always|never"), Ungated),
+    (sym::link, Whitelisted, template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...",
                                                /*opt*/ cfg = "...""#), Ungated),
-    (symbols::link_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
-    (symbols::link_section, Whitelisted, template!(NameValueStr: "name"), Ungated),
-    (symbols::no_builtins, Whitelisted, template!(Word), Ungated),
-    (symbols::no_debug, Whitelisted, template!(Word), Gated(
+    (sym::link_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
+    (sym::link_section, Whitelisted, template!(NameValueStr: "name"), Ungated),
+    (sym::no_builtins, Whitelisted, template!(Word), Ungated),
+    (sym::no_debug, Whitelisted, template!(Word), Gated(
         Stability::Deprecated("https://github.com/rust-lang/rust/issues/29721", None),
-        "no_debug",
+        sym::no_debug,
         "the `#[no_debug]` attribute was an experimental feature that has been \
         deprecated due to lack of demand",
         cfg_fn!(no_debug))),
     (
-        symbols::omit_gdb_pretty_printer_section,
+        sym::omit_gdb_pretty_printer_section,
         Whitelisted,
         template!(Word),
         Gated(
             Stability::Unstable,
-            "omit_gdb_pretty_printer_section",
+            sym::omit_gdb_pretty_printer_section,
             "the `#[omit_gdb_pretty_printer_section]` \
                 attribute is just used for the Rust test \
                 suite",
             cfg_fn!(omit_gdb_pretty_printer_section)
         )
     ),
-    (symbols::unsafe_destructor_blind_to_params,
+    (sym::unsafe_destructor_blind_to_params,
     Normal,
     template!(Word),
     Gated(Stability::Deprecated("https://github.com/rust-lang/rust/issues/34761",
                                 Some("replace this attribute with `#[may_dangle]`")),
-        "dropck_parametricity",
+        sym::dropck_parametricity,
         "unsafe_destructor_blind_to_params has been replaced by \
             may_dangle and will be removed in the future",
         cfg_fn!(dropck_parametricity))),
-    (symbols::may_dangle,
+    (sym::may_dangle,
     Normal,
     template!(Word),
     Gated(Stability::Unstable,
-        "dropck_eyepatch",
+        sym::dropck_eyepatch,
         "may_dangle has unstable semantics and may be removed in the future",
         cfg_fn!(dropck_eyepatch))),
-    (symbols::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable,
-                                "unwind_attributes",
+    (sym::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable,
+                                sym::unwind_attributes,
                                 "#[unwind] is experimental",
                                 cfg_fn!(unwind_attributes))),
-    (symbols::used, Whitelisted, template!(Word), Ungated),
+    (sym::used, Whitelisted, template!(Word), Ungated),
 
     // used in resolve
-    (symbols::prelude_import, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        "prelude_import",
+    (sym::prelude_import, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                        sym::prelude_import,
                                         "`#[prelude_import]` is for use by rustc only",
                                         cfg_fn!(prelude_import))),
 
     // FIXME: #14407 these are only looked at on-demand so we can't
     // guarantee they'll have already been checked
     (
-        symbols::rustc_deprecated,
+        sym::rustc_deprecated,
         Whitelisted,
         template!(List: r#"since = "version", reason = "...""#),
         Ungated
     ),
-    (symbols::must_use, Whitelisted, template!(Word, NameValueStr: "reason"), Ungated),
+    (sym::must_use, Whitelisted, template!(Word, NameValueStr: "reason"), Ungated),
     (
-        symbols::stable,
+        sym::stable,
         Whitelisted,
         template!(List: r#"feature = "name", since = "version""#),
         Ungated
     ),
     (
-        symbols::unstable,
+        sym::unstable,
         Whitelisted,
         template!(List: r#"feature = "name", reason = "...", issue = "N""#),
         Ungated
     ),
-    (symbols::deprecated,
+    (sym::deprecated,
         Normal,
         template!(
             Word,
@@ -1420,70 +1421,71 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
         Ungated
     ),
 
-    (symbols::rustc_paren_sugar, Normal, template!(Word), Gated(Stability::Unstable,
-                                        "unboxed_closures",
+    (sym::rustc_paren_sugar, Normal, template!(Word), Gated(Stability::Unstable,
+                                        sym::unboxed_closures,
                                         "unboxed_closures are still evolving",
                                         cfg_fn!(unboxed_closures))),
 
-    (symbols::windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console"), Ungated),
+    (sym::windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console"), Ungated),
 
-    (symbols::proc_macro_attribute, Normal, template!(Word), Ungated),
-    (symbols::proc_macro, Normal, template!(Word), Ungated),
+    (sym::proc_macro_attribute, Normal, template!(Word), Ungated),
+    (sym::proc_macro, Normal, template!(Word), Ungated),
 
-    (symbols::rustc_proc_macro_decls, Normal, template!(Word), Gated(Stability::Unstable,
-                                            "rustc_attrs",
+    (sym::rustc_proc_macro_decls, Normal, template!(Word), Gated(Stability::Unstable,
+                                            sym::rustc_attrs,
                                             "used internally by rustc",
                                             cfg_fn!(rustc_attrs))),
 
-    (symbols::allow_fail, Normal, template!(Word), Gated(Stability::Unstable,
-                                "allow_fail",
+    (sym::allow_fail, Normal, template!(Word), Gated(Stability::Unstable,
+                                sym::allow_fail,
                                 "allow_fail attribute is currently unstable",
                                 cfg_fn!(allow_fail))),
 
-    (symbols::rustc_std_internal_symbol, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    "rustc_attrs",
+    (sym::rustc_std_internal_symbol, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
                                     "this is an internal attribute that will \
                                     never be stable",
                                     cfg_fn!(rustc_attrs))),
 
     // whitelists "identity-like" conversion methods to suggest on type mismatch
-    (symbols::rustc_conversion_suggestion, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    "rustc_attrs",
+    (sym::rustc_conversion_suggestion, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                    sym::rustc_attrs,
                                                     "this is an internal attribute that will \
                                                         never be stable",
                                                     cfg_fn!(rustc_attrs))),
 
     (
-        symbols::rustc_args_required_const,
+        sym::rustc_args_required_const,
         Whitelisted,
         template!(List: "N"),
-        Gated(Stability::Unstable, "rustc_attrs", "never will be stable", cfg_fn!(rustc_attrs))
+        Gated(Stability::Unstable, sym::rustc_attrs, "never will be stable",
+           cfg_fn!(rustc_attrs))
     ),
     // RFC 2070
-    (symbols::panic_handler, Normal, template!(Word), Ungated),
+    (sym::panic_handler, Normal, template!(Word), Ungated),
 
-    (symbols::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable,
-                        "alloc_error_handler",
+    (sym::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable,
+                        sym::alloc_error_handler,
                         "#[alloc_error_handler] is an unstable feature",
                         cfg_fn!(alloc_error_handler))),
 
     // RFC 2412
-    (symbols::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable,
-                            "optimize_attribute",
+    (sym::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable,
+                            sym::optimize_attribute,
                             "#[optimize] attribute is an unstable feature",
                             cfg_fn!(optimize_attribute))),
 
     // Crate level attributes
-    (symbols::crate_name, CrateLevel, template!(NameValueStr: "name"), Ungated),
-    (symbols::crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), Ungated),
-    (symbols::crate_id, CrateLevel, template!(NameValueStr: "ignored"), Ungated),
-    (symbols::feature, CrateLevel, template!(List: "name1, name1, ..."), Ungated),
-    (symbols::no_start, CrateLevel, template!(Word), Ungated),
-    (symbols::no_main, CrateLevel, template!(Word), Ungated),
-    (symbols::recursion_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
-    (symbols::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
-    (symbols::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable,
-                    "custom_test_frameworks",
+    (sym::crate_name, CrateLevel, template!(NameValueStr: "name"), Ungated),
+    (sym::crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), Ungated),
+    (sym::crate_id, CrateLevel, template!(NameValueStr: "ignored"), Ungated),
+    (sym::feature, CrateLevel, template!(List: "name1, name1, ..."), Ungated),
+    (sym::no_start, CrateLevel, template!(Word), Ungated),
+    (sym::no_main, CrateLevel, template!(Word), Ungated),
+    (sym::recursion_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
+    (sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
+    (sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable,
+                    sym::custom_test_frameworks,
                     EXPLAIN_CUSTOM_TEST_FRAMEWORKS,
                     cfg_fn!(custom_test_frameworks))),
 ];
@@ -1503,11 +1505,11 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
 }
 
 // cfg(...)'s that are feature gated
-const GATED_CFGS: &[(&str, &str, fn(&Features) -> bool)] = &[
+const GATED_CFGS: &[(Symbol, Symbol, fn(&Features) -> bool)] = &[
     // (name in cfg, feature, function to check if the feature is enabled)
-    ("target_thread_local", "cfg_target_thread_local", cfg_fn!(cfg_target_thread_local)),
-    ("target_has_atomic", "cfg_target_has_atomic", cfg_fn!(cfg_target_has_atomic)),
-    ("rustdoc", "doc_cfg", cfg_fn!(doc_cfg)),
+    (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
+    (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
+    (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)),
 ];
 
 #[derive(Debug)]
@@ -1540,7 +1542,7 @@ pub fn check_and_emit(&self, sess: &ParseSess, features: &Features) {
 struct Context<'a> {
     features: &'a Features,
     parse_sess: &'a ParseSess,
-    plugin_attributes: &'a [(String, AttributeType)],
+    plugin_attributes: &'a [(Symbol, AttributeType)],
 }
 
 macro_rules! gate_feature_fn {
@@ -1559,11 +1561,11 @@ macro_rules! gate_feature_fn {
 macro_rules! gate_feature {
     ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {
         gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
-                         stringify!($feature), $explain, GateStrength::Hard)
+                         sym::$feature, $explain, GateStrength::Hard)
     };
     ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {
         gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
-                         stringify!($feature), $explain, $level)
+                         sym::$feature, $explain, $level)
     };
 }
 
@@ -1582,9 +1584,9 @@ fn check_attribute(
                         self, has_feature, attr.span, name, desc, GateStrength::Hard
                     );
                 }
-            } else if name == symbols::doc {
+            } else if name == sym::doc {
                 if let Some(content) = attr.meta_item_list() {
-                    if content.iter().any(|c| c.check_name(symbols::include)) {
+                    if content.iter().any(|c| c.check_name(sym::include)) {
                         gate_feature!(self, external_doc, attr.span,
                             "#[doc(include = \"...\")] is experimental"
                         );
@@ -1594,8 +1596,8 @@ fn check_attribute(
             debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage);
             return;
         }
-        for &(ref n, ref ty) in self.plugin_attributes {
-            if attr.path == &**n {
+        for &(n, ty) in self.plugin_attributes {
+            if attr.path == n {
                 // Plugins can't gate attributes, so we don't check for it
                 // unlike the code above; we only use this loop to
                 // short-circuit to avoid the checks below.
@@ -1604,7 +1606,7 @@ fn check_attribute(
             }
         }
         if !attr::is_known(attr) {
-            if attr.name_or_empty().starts_with("rustc_") {
+            if attr.name_or_empty().as_str().starts_with("rustc_") {
                 let msg = "unless otherwise specified, attributes with the prefix `rustc_` \
                            are reserved for internal compiler diagnostics";
                 gate_feature!(self, rustc_attrs, attr.span, msg);
@@ -1629,7 +1631,7 @@ pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features:
     );
 }
 
-fn find_lang_feature_issue(feature: &str) -> Option<u32> {
+fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
     if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) {
         let issue = info.2;
         // FIXME (#28244): enforce that active features have issue numbers
@@ -1661,7 +1663,7 @@ pub enum GateStrength {
 
 pub fn emit_feature_err(
     sess: &ParseSess,
-    feature: &str,
+    feature: Symbol,
     span: Span,
     issue: GateIssue,
     explain: &str,
@@ -1671,7 +1673,7 @@ pub fn emit_feature_err(
 
 pub fn feature_err<'a>(
     sess: &'a ParseSess,
-    feature: &str,
+    feature: Symbol,
     span: Span,
     issue: GateIssue,
     explain: &str,
@@ -1681,7 +1683,7 @@ pub fn feature_err<'a>(
 
 fn leveled_feature_err<'a>(
     sess: &'a ParseSess,
-    feature: &str,
+    feature: Symbol,
     span: Span,
     issue: GateIssue,
     explain: &str,
@@ -1769,13 +1771,13 @@ struct PostExpansionVisitor<'a> {
 macro_rules! gate_feature_post {
     ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{
         let (cx, span) = ($cx, $span);
-        if !span.allows_unstable(stringify!($feature)) {
+        if !span.allows_unstable(sym::$feature) {
             gate_feature!(cx.context, $feature, span, $explain)
         }
     }};
     ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{
         let (cx, span) = ($cx, $span);
-        if !span.allows_unstable(stringify!($feature)) {
+        if !span.allows_unstable(sym::$feature) {
             gate_feature!(cx.context, $feature, span, $explain, $level)
         }
     }}
@@ -1841,11 +1843,11 @@ fn check_builtin_attribute(&mut self, attr: &ast::Attribute, name: Symbol,
                                template: AttributeTemplate) {
         // Some special attributes like `cfg` must be checked
         // before the generic check, so we skip them here.
-        let should_skip = |name| name == symbols::cfg;
+        let should_skip = |name| name == sym::cfg;
         // Some of previously accepted forms were used in practice,
         // report them as warnings for now.
-        let should_warn = |name| name == symbols::doc || name == symbols::ignore ||
-                                 name == symbols::inline || name == symbols::link;
+        let should_warn = |name| name == sym::doc || name == sym::ignore ||
+                                 name == sym::inline || name == sym::link;
 
         match attr.parse_meta(self.context.parse_sess) {
             Ok(meta) => if !should_skip(name) && !template.compatible(&meta.node) {
@@ -1893,25 +1895,25 @@ fn visit_attribute(&mut self, attr: &ast::Attribute) {
         // check for gated attributes
         self.context.check_attribute(attr, attr_info, false);
 
-        if attr.check_name(symbols::doc) {
+        if attr.check_name(sym::doc) {
             if let Some(content) = attr.meta_item_list() {
-                if content.len() == 1 && content[0].check_name(symbols::cfg) {
+                if content.len() == 1 && content[0].check_name(sym::cfg) {
                     gate_feature_post!(&self, doc_cfg, attr.span,
                         "#[doc(cfg(...))] is experimental"
                     );
-                } else if content.iter().any(|c| c.check_name(symbols::masked)) {
+                } else if content.iter().any(|c| c.check_name(sym::masked)) {
                     gate_feature_post!(&self, doc_masked, attr.span,
                         "#[doc(masked)] is experimental"
                     );
-                } else if content.iter().any(|c| c.check_name(symbols::spotlight)) {
+                } else if content.iter().any(|c| c.check_name(sym::spotlight)) {
                     gate_feature_post!(&self, doc_spotlight, attr.span,
                         "#[doc(spotlight)] is experimental"
                     );
-                } else if content.iter().any(|c| c.check_name(symbols::alias)) {
+                } else if content.iter().any(|c| c.check_name(sym::alias)) {
                     gate_feature_post!(&self, doc_alias, attr.span,
                         "#[doc(alias = \"...\")] is experimental"
                     );
-                } else if content.iter().any(|c| c.check_name(symbols::keyword)) {
+                } else if content.iter().any(|c| c.check_name(sym::keyword)) {
                     gate_feature_post!(&self, doc_keyword, attr.span,
                         "#[doc(keyword = \"...\")] is experimental"
                     );
@@ -1946,7 +1948,7 @@ fn visit_name(&mut self, sp: Span, name: ast::Name) {
     fn visit_item(&mut self, i: &'a ast::Item) {
         match i.node {
             ast::ItemKind::Const(_,_) => {
-                if i.ident.name == "_" {
+                if i.ident.name == keywords::Underscore.name() {
                     gate_feature_post!(&self, underscore_const_names, i.span,
                                         "naming constants with `_` is unstable");
                 }
@@ -1957,17 +1959,17 @@ fn visit_item(&mut self, i: &'a ast::Item) {
             }
 
             ast::ItemKind::Fn(..) => {
-                if attr::contains_name(&i.attrs[..], "plugin_registrar") {
+                if attr::contains_name(&i.attrs[..], sym::plugin_registrar) {
                     gate_feature_post!(&self, plugin_registrar, i.span,
                                        "compiler plugins are experimental and possibly buggy");
                 }
-                if attr::contains_name(&i.attrs[..], "start") {
+                if attr::contains_name(&i.attrs[..], sym::start) {
                     gate_feature_post!(&self, 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[..], sym::main) {
                     gate_feature_post!(&self, main, i.span,
                                        "declaration of a nonstandard #[main] \
                                         function may change over time, for now \
@@ -1976,9 +1978,9 @@ fn visit_item(&mut self, i: &'a ast::Item) {
             }
 
             ast::ItemKind::Struct(..) => {
-                for attr in attr::filter_by_name(&i.attrs[..], "repr") {
+                for attr in attr::filter_by_name(&i.attrs[..], sym::repr) {
                     for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
-                        if item.check_name(symbols::simd) {
+                        if item.check_name(sym::simd) {
                             gate_feature_post!(&self, repr_simd, attr.span,
                                                "SIMD types are experimental and possibly buggy");
                         }
@@ -1987,9 +1989,9 @@ fn visit_item(&mut self, i: &'a ast::Item) {
             }
 
             ast::ItemKind::Enum(..) => {
-                for attr in attr::filter_by_name(&i.attrs[..], "repr") {
+                for attr in attr::filter_by_name(&i.attrs[..], sym::repr) {
                     for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
-                        if item.check_name(symbols::align) {
+                        if item.check_name(sym::align) {
                             gate_feature_post!(&self, repr_align_enum, attr.span,
                                                "`#[repr(align(x))]` on enums is experimental");
                         }
@@ -2051,7 +2053,7 @@ fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) {
         match i.node {
             ast::ForeignItemKind::Fn(..) |
             ast::ForeignItemKind::Static(..) => {
-                let link_name = attr::first_attr_value_str_by_name(&i.attrs, "link_name");
+                let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name);
                 let links_to_llvm = match link_name {
                     Some(val) => val.as_str().starts_with("llvm."),
                     _ => false
@@ -2303,7 +2305,7 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
         if edition <= crate_edition {
             // The `crate_edition` implies its respective umbrella feature-gate
             // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
-            edition_enabled_features.insert(Symbol::intern(edition.feature_name()), edition);
+            edition_enabled_features.insert(edition.feature_name(), edition);
         }
     }
 
@@ -2311,7 +2313,7 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
         if let Some(f_edition) = f_edition {
             if f_edition <= crate_edition {
                 set(&mut features, DUMMY_SP);
-                edition_enabled_features.insert(Symbol::intern(name), crate_edition);
+                edition_enabled_features.insert(name, crate_edition);
             }
         }
     }
@@ -2319,7 +2321,7 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
     // Process the edition umbrella feature-gates first, to ensure
     // `edition_enabled_features` is completed before it's queried.
     for attr in krate_attrs {
-        if !attr.check_name(symbols::feature) {
+        if !attr.check_name(sym::feature) {
             continue
         }
 
@@ -2355,7 +2357,7 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
                             // FIXME(Manishearth) there is currently no way to set
                             // lib features by edition
                             set(&mut features, DUMMY_SP);
-                            edition_enabled_features.insert(Symbol::intern(name), *edition);
+                            edition_enabled_features.insert(name, *edition);
                         }
                     }
                 }
@@ -2364,7 +2366,7 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
     }
 
     for attr in krate_attrs {
-        if !attr.check_name(symbols::feature) {
+        if !attr.check_name(sym::feature) {
             continue
         }
 
@@ -2438,7 +2440,7 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
 pub fn check_crate(krate: &ast::Crate,
                    sess: &ParseSess,
                    features: &Features,
-                   plugin_attributes: &[(String, AttributeType)],
+                   plugin_attributes: &[(Symbol, AttributeType)],
                    unstable: UnstableFeatures) {
     maybe_stage_features(&sess.span_diagnostic, krate, unstable);
     let ctx = Context {
@@ -2496,7 +2498,7 @@ fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate,
     };
     if !allow_features {
         for attr in &krate.attrs {
-            if attr.check_name(symbols::feature) {
+            if attr.check_name(sym::feature) {
                 let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)");
                 span_err!(span_handler, attr.span, E0554,
                           "#![feature] may not be used on the {} release channel",
index 6eb8b1b5004c96468958756878d0dbcf8a7b7b28..f587e63e12b94b428e663f79a97c71a65c3bc754 100644 (file)
@@ -663,7 +663,6 @@ pub fn noop_visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis:
         token::NtMeta(meta) => vis.visit_meta_item(meta),
         token::NtPath(path) => vis.visit_path(path),
         token::NtTT(tt) => vis.visit_tt(tt),
-        token::NtArm(arm) => vis.visit_arm(arm),
         token::NtImplItem(item) =>
             visit_clobber(item, |item| {
                 // See reasoning above.
@@ -676,9 +675,6 @@ pub fn noop_visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis:
                 vis.flat_map_trait_item(item)
                     .expect_one("expected visitor to produce exactly one item")
             }),
-        token::NtGenerics(generics) => vis.visit_generics(generics),
-        token::NtWhereClause(where_clause) => vis.visit_where_clause(where_clause),
-        token::NtArg(arg) => vis.visit_arg(arg),
         token::NtVis(visib) => vis.visit_vis(visib),
         token::NtForeignItem(item) =>
             visit_clobber(item, |item| {
index b4103440e357719e00e2637bb71a0e42aaecbe9d..dfd6f451c28d7779a3f2c50af7f3a8b772aa1a20 100644 (file)
@@ -25,16 +25,3 @@ pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
         _ => true,
     }
 }
-
-/// this statement requires a semicolon after it.
-/// note that in one case (`stmt_semi`), we've already
-/// seen the semicolon, and thus don't need another.
-pub fn stmt_ends_with_semi(stmt: &ast::StmtKind) -> bool {
-    match *stmt {
-        ast::StmtKind::Local(_) => true,
-        ast::StmtKind::Expr(ref e) => expr_requires_semi_to_be_stmt(e),
-        ast::StmtKind::Item(_) |
-        ast::StmtKind::Semi(..) |
-        ast::StmtKind::Mac(..) => false,
-    }
-}
index 74fff3324eacf62e9cb6d5df08f489288cd87322..97d3fc002e9b0de49c84623274564834c2e54dbe 100644 (file)
@@ -3,8 +3,7 @@
 use crate::ast;
 use crate::source_map::SourceMap;
 use crate::parse::lexer::{is_block_doc_comment, is_pattern_whitespace};
-use crate::parse::lexer::{self, ParseSess, StringReader, TokenAndSpan};
-use crate::print::pprust;
+use crate::parse::lexer::{self, ParseSess, StringReader};
 
 use syntax_pos::{BytePos, CharPos, Pos, FileName};
 use log::debug;
@@ -339,16 +338,9 @@ fn consume_comment(rdr: &mut StringReader<'_>,
     debug!("<<< consume comment");
 }
 
-#[derive(Clone)]
-pub struct Literal {
-    pub lit: String,
-    pub pos: BytePos,
-}
-
 // it appears this function is called only from pprust... that's
 // probably not a good thing.
-pub fn gather_comments_and_literals(sess: &ParseSess, path: FileName, srdr: &mut dyn Read)
-    -> (Vec<Comment>, Vec<Literal>)
+pub fn gather_comments(sess: &ParseSess, path: FileName, srdr: &mut dyn Read) -> Vec<Comment>
 {
     let mut src = String::new();
     srdr.read_to_string(&mut src).unwrap();
@@ -357,7 +349,6 @@ pub fn gather_comments_and_literals(sess: &ParseSess, path: FileName, srdr: &mut
     let mut rdr = lexer::StringReader::new_raw(sess, source_file, None);
 
     let mut comments: Vec<Comment> = Vec::new();
-    let mut literals: Vec<Literal> = Vec::new();
     let mut code_to_the_left = false; // Only code
     let mut anything_to_the_left = false; // Code or comments
 
@@ -382,26 +373,12 @@ pub fn gather_comments_and_literals(sess: &ParseSess, path: FileName, srdr: &mut
             }
         }
 
-        let bstart = rdr.pos;
         rdr.next_token();
-        // discard, and look ahead; we're working with internal state
-        let TokenAndSpan { tok, sp } = rdr.peek();
-        if tok.is_lit() {
-            rdr.with_str_from(bstart, |s| {
-                debug!("tok lit: {}", s);
-                literals.push(Literal {
-                    lit: s.to_string(),
-                    pos: sp.lo(),
-                });
-            })
-        } else {
-            debug!("tok: {}", pprust::token_to_string(&tok));
-        }
         code_to_the_left = true;
         anything_to_the_left = true;
     }
 
-    (comments, literals)
+    comments
 }
 
 #[cfg(test)]
index 9caa9ea807c1d473b2b5c1c304356ce559e41907..47da3ee6a6c7817c1b770f9d2fd00cc884737db9 100644 (file)
@@ -238,18 +238,6 @@ fn new_raw_internal(sess: &'a ParseSess, source_file: Lrc<syntax_pos::SourceFile
         }
     }
 
-    pub fn new(sess: &'a ParseSess,
-               source_file: Lrc<syntax_pos::SourceFile>,
-               override_span: Option<Span>) -> Self {
-        let mut sr = StringReader::new_raw(sess, source_file, override_span);
-        if sr.advance_token().is_err() {
-            sr.emit_fatal_errors();
-            FatalError.raise();
-        }
-
-        sr
-    }
-
     pub fn new_or_buffered_errs(sess: &'a ParseSess,
                                 source_file: Lrc<syntax_pos::SourceFile>,
                                 override_span: Option<Span>) -> Result<Self, Vec<Diagnostic>> {
@@ -1603,7 +1591,12 @@ fn setup<'a>(sm: &SourceMap,
                  teststr: String)
                  -> StringReader<'a> {
         let sf = sm.new_source_file(PathBuf::from(teststr.clone()).into(), teststr);
-        StringReader::new(sess, sf, None)
+        let mut sr = StringReader::new_raw(sess, sf, None);
+        if sr.advance_token().is_err() {
+            sr.emit_fatal_errors();
+            FatalError.raise();
+        }
+        sr
     }
 
     #[test]
diff --git a/src/libsyntax/parse/literal.rs b/src/libsyntax/parse/literal.rs
new file mode 100644 (file)
index 0000000..5319542
--- /dev/null
@@ -0,0 +1,487 @@
+//! Code related to parsing literals.
+
+use crate::ast::{self, Ident, Lit, LitKind};
+use crate::parse::parser::Parser;
+use crate::parse::PResult;
+use crate::parse::token::{self, Token};
+use crate::parse::unescape::{unescape_str, unescape_char, unescape_byte_str, unescape_byte};
+use crate::print::pprust;
+use crate::symbol::{keywords, Symbol};
+use crate::tokenstream::{TokenStream, TokenTree};
+
+use errors::{Applicability, Handler};
+use log::debug;
+use rustc_data_structures::sync::Lrc;
+use syntax_pos::Span;
+
+use std::ascii;
+
+macro_rules! err {
+    ($opt_diag:expr, |$span:ident, $diag:ident| $($body:tt)*) => {
+        match $opt_diag {
+            Some(($span, $diag)) => { $($body)* }
+            None => return None,
+        }
+    }
+}
+
+impl LitKind {
+    /// Converts literal token with a suffix into a semantic literal.
+    /// Works speculatively and may return `None` if diagnostic handler is not passed.
+    /// If diagnostic handler is passed, always returns `Some`,
+    /// possibly after reporting non-fatal errors and recovery.
+    fn from_lit_token(
+        lit: token::Lit,
+        suf: Option<Symbol>,
+        diag: Option<(Span, &Handler)>
+    ) -> Option<LitKind> {
+        if suf.is_some() && !lit.may_have_suffix() {
+            err!(diag, |span, diag| {
+                expect_no_suffix(span, diag, &format!("a {}", lit.literal_name()), suf)
+            });
+        }
+
+        Some(match lit {
+            token::Bool(i) => {
+                assert!(i == keywords::True.name() || i == keywords::False.name());
+                LitKind::Bool(i == keywords::True.name())
+            }
+            token::Byte(i) => {
+                match unescape_byte(&i.as_str()) {
+                    Ok(c) => LitKind::Byte(c),
+                    Err(_) => LitKind::Err(i),
+                }
+            },
+            token::Char(i) => {
+                match unescape_char(&i.as_str()) {
+                    Ok(c) => LitKind::Char(c),
+                    Err(_) => LitKind::Err(i),
+                }
+            },
+            token::Err(i) => LitKind::Err(i),
+
+            // There are some valid suffixes for integer and float literals,
+            // so all the handling is done internally.
+            token::Integer(s) => return integer_lit(&s.as_str(), suf, diag),
+            token::Float(s) => return float_lit(&s.as_str(), suf, diag),
+
+            token::Str_(mut sym) => {
+                // If there are no characters requiring special treatment we can
+                // reuse the symbol from the Token. Otherwise, we must generate a
+                // new symbol because the string in the LitKind is different to the
+                // string in the Token.
+                let mut has_error = false;
+                let s = &sym.as_str();
+                if s.as_bytes().iter().any(|&c| c == b'\\' || c == b'\r') {
+                    let mut buf = String::with_capacity(s.len());
+                    unescape_str(s, &mut |_, unescaped_char| {
+                        match unescaped_char {
+                            Ok(c) => buf.push(c),
+                            Err(_) => has_error = true,
+                        }
+                    });
+                    if has_error {
+                        return Some(LitKind::Err(sym));
+                    }
+                    sym = Symbol::intern(&buf)
+                }
+
+                LitKind::Str(sym, ast::StrStyle::Cooked)
+            }
+            token::StrRaw(mut sym, n) => {
+                // Ditto.
+                let s = &sym.as_str();
+                if s.contains('\r') {
+                    sym = Symbol::intern(&raw_str_lit(s));
+                }
+                LitKind::Str(sym, ast::StrStyle::Raw(n))
+            }
+            token::ByteStr(i) => {
+                let s = &i.as_str();
+                let mut buf = Vec::with_capacity(s.len());
+                let mut has_error = false;
+                unescape_byte_str(s, &mut |_, unescaped_byte| {
+                    match unescaped_byte {
+                        Ok(c) => buf.push(c),
+                        Err(_) => has_error = true,
+                    }
+                });
+                if has_error {
+                    return Some(LitKind::Err(i));
+                }
+                buf.shrink_to_fit();
+                LitKind::ByteStr(Lrc::new(buf))
+            }
+            token::ByteStrRaw(i, _) => {
+                LitKind::ByteStr(Lrc::new(i.to_string().into_bytes()))
+            }
+        })
+    }
+
+    /// Attempts to recover a token from semantic literal.
+    /// This function is used when the original token doesn't exist (e.g. the literal is created
+    /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing).
+    pub fn to_lit_token(&self) -> (token::Lit, Option<Symbol>) {
+        match *self {
+            LitKind::Str(string, ast::StrStyle::Cooked) => {
+                let escaped = string.as_str().escape_default().to_string();
+                (token::Lit::Str_(Symbol::intern(&escaped)), None)
+            }
+            LitKind::Str(string, ast::StrStyle::Raw(n)) => {
+                (token::Lit::StrRaw(string, n), None)
+            }
+            LitKind::ByteStr(ref bytes) => {
+                let string = bytes.iter().cloned().flat_map(ascii::escape_default)
+                    .map(Into::<char>::into).collect::<String>();
+                (token::Lit::ByteStr(Symbol::intern(&string)), None)
+            }
+            LitKind::Byte(byte) => {
+                let string: String = ascii::escape_default(byte).map(Into::<char>::into).collect();
+                (token::Lit::Byte(Symbol::intern(&string)), None)
+            }
+            LitKind::Char(ch) => {
+                let string: String = ch.escape_default().map(Into::<char>::into).collect();
+                (token::Lit::Char(Symbol::intern(&string)), None)
+            }
+            LitKind::Int(n, ty) => {
+                let suffix = match ty {
+                    ast::LitIntType::Unsigned(ty) => Some(Symbol::intern(ty.ty_to_string())),
+                    ast::LitIntType::Signed(ty) => Some(Symbol::intern(ty.ty_to_string())),
+                    ast::LitIntType::Unsuffixed => None,
+                };
+                (token::Lit::Integer(Symbol::intern(&n.to_string())), suffix)
+            }
+            LitKind::Float(symbol, ty) => {
+                (token::Lit::Float(symbol), Some(Symbol::intern(ty.ty_to_string())))
+            }
+            LitKind::FloatUnsuffixed(symbol) => (token::Lit::Float(symbol), None),
+            LitKind::Bool(value) => {
+                let kw = if value { keywords::True } else { keywords::False };
+                (token::Lit::Bool(kw.name()), None)
+            }
+            LitKind::Err(val) => (token::Lit::Err(val), None),
+        }
+    }
+}
+
+impl Lit {
+    /// Converts literal token with a suffix into an AST literal.
+    /// Works speculatively and may return `None` if diagnostic handler is not passed.
+    /// If diagnostic handler is passed, may return `Some`,
+    /// possibly after reporting non-fatal errors and recovery, or `None` for irrecoverable errors.
+    crate fn from_token(
+        token: &token::Token,
+        span: Span,
+        diag: Option<(Span, &Handler)>,
+    ) -> Option<Lit> {
+        let (token, suffix) = match *token {
+            token::Ident(ident, false) if ident.name == keywords::True.name() ||
+                                          ident.name == keywords::False.name() =>
+                (token::Bool(ident.name), None),
+            token::Literal(token, suffix) =>
+                (token, suffix),
+            token::Interpolated(ref nt) => {
+                if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt {
+                    if let ast::ExprKind::Lit(lit) = &expr.node {
+                        return Some(lit.clone());
+                    }
+                }
+                return None;
+            }
+            _ => return None,
+        };
+
+        let node = LitKind::from_lit_token(token, suffix, diag)?;
+        Some(Lit { node, token, suffix, span })
+    }
+
+    /// Attempts to recover an AST literal from semantic literal.
+    /// This function is used when the original token doesn't exist (e.g. the literal is created
+    /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing).
+    pub fn from_lit_kind(node: LitKind, span: Span) -> Lit {
+        let (token, suffix) = node.to_lit_token();
+        Lit { node, token, suffix, span }
+    }
+
+    /// Losslessly convert an AST literal into a token stream.
+    crate fn tokens(&self) -> TokenStream {
+        let token = match self.token {
+            token::Bool(symbol) => Token::Ident(Ident::with_empty_ctxt(symbol), false),
+            token => Token::Literal(token, self.suffix),
+        };
+        TokenTree::Token(self.span, token).into()
+    }
+}
+
+impl<'a> Parser<'a> {
+    /// Matches `lit = true | false | token_lit`.
+    crate fn parse_lit(&mut self) -> PResult<'a, Lit> {
+        let diag = Some((self.span, &self.sess.span_diagnostic));
+        if let Some(lit) = Lit::from_token(&self.token, self.span, diag) {
+            self.bump();
+            return Ok(lit);
+        } else if self.token == token::Dot {
+            // Recover `.4` as `0.4`.
+            let recovered = self.look_ahead(1, |t| {
+                if let token::Literal(token::Integer(val), suf) = *t {
+                    let next_span = self.look_ahead_span(1);
+                    if self.span.hi() == next_span.lo() {
+                        let sym = String::from("0.") + &val.as_str();
+                        let token = token::Literal(token::Float(Symbol::intern(&sym)), suf);
+                        return Some((token, self.span.to(next_span)));
+                    }
+                }
+                None
+            });
+            if let Some((token, span)) = recovered {
+                self.diagnostic()
+                    .struct_span_err(span, "float literals must have an integer part")
+                    .span_suggestion(
+                        span,
+                        "must have an integer part",
+                        pprust::token_to_string(&token),
+                        Applicability::MachineApplicable,
+                    )
+                    .emit();
+                let diag = Some((span, &self.sess.span_diagnostic));
+                if let Some(lit) = Lit::from_token(&token, span, diag) {
+                    self.bump();
+                    self.bump();
+                    return Ok(lit);
+                }
+            }
+        }
+
+        Err(self.span_fatal(self.span, &format!("unexpected token: {}", self.this_token_descr())))
+    }
+}
+
+crate fn expect_no_suffix(sp: Span, diag: &Handler, kind: &str, suffix: Option<ast::Name>) {
+    match suffix {
+        None => {/* everything ok */}
+        Some(suf) => {
+            let text = suf.as_str();
+            if text.is_empty() {
+                diag.span_bug(sp, "found empty literal suffix in Some")
+            }
+            let mut err = if kind == "a tuple index" &&
+                ["i32", "u32", "isize", "usize"].contains(&text.to_string().as_str())
+            {
+                // #59553: warn instead of reject out of hand to allow the fix to percolate
+                // through the ecosystem when people fix their macros
+                let mut err = diag.struct_span_warn(
+                    sp,
+                    &format!("suffixes on {} are invalid", kind),
+                );
+                err.note(&format!(
+                    "`{}` is *temporarily* accepted on tuple index fields as it was \
+                        incorrectly accepted on stable for a few releases",
+                    text,
+                ));
+                err.help(
+                    "on proc macros, you'll want to use `syn::Index::from` or \
+                        `proc_macro::Literal::*_unsuffixed` for code that will desugar \
+                        to tuple field access",
+                );
+                err.note(
+                    "for more context, see https://github.com/rust-lang/rust/issues/60210",
+                );
+                err
+            } else {
+                diag.struct_span_err(sp, &format!("suffixes on {} are invalid", kind))
+            };
+            err.span_label(sp, format!("invalid suffix `{}`", text));
+            err.emit();
+        }
+    }
+}
+
+/// Parses a string representing a raw string literal into its final form. The
+/// only operation this does is convert embedded CRLF into a single LF.
+fn raw_str_lit(lit: &str) -> String {
+    debug!("raw_str_lit: given {}", lit.escape_default());
+    let mut res = String::with_capacity(lit.len());
+
+    let mut chars = lit.chars().peekable();
+    while let Some(c) = chars.next() {
+        if c == '\r' {
+            if *chars.peek().unwrap() != '\n' {
+                panic!("lexer accepted bare CR");
+            }
+            chars.next();
+            res.push('\n');
+        } else {
+            res.push(c);
+        }
+    }
+
+    res.shrink_to_fit();
+    res
+}
+
+// check if `s` looks like i32 or u1234 etc.
+fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
+    s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit())
+}
+
+fn filtered_float_lit(data: Symbol, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>)
+                      -> Option<LitKind> {
+    debug!("filtered_float_lit: {}, {:?}", data, suffix);
+    let suffix = match suffix {
+        Some(suffix) => suffix,
+        None => return Some(LitKind::FloatUnsuffixed(data)),
+    };
+
+    Some(match &*suffix.as_str() {
+        "f32" => LitKind::Float(data, ast::FloatTy::F32),
+        "f64" => LitKind::Float(data, ast::FloatTy::F64),
+        suf => {
+            err!(diag, |span, diag| {
+                if suf.len() >= 2 && looks_like_width_suffix(&['f'], suf) {
+                    // if it looks like a width, lets try to be helpful.
+                    let msg = format!("invalid width `{}` for float literal", &suf[1..]);
+                    diag.struct_span_err(span, &msg).help("valid widths are 32 and 64").emit()
+                } else {
+                    let msg = format!("invalid suffix `{}` for float literal", suf);
+                    diag.struct_span_err(span, &msg)
+                        .span_label(span, format!("invalid suffix `{}`", suf))
+                        .help("valid suffixes are `f32` and `f64`")
+                        .emit();
+                }
+            });
+
+            LitKind::FloatUnsuffixed(data)
+        }
+    })
+}
+fn float_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>)
+                 -> Option<LitKind> {
+    debug!("float_lit: {:?}, {:?}", s, suffix);
+    // FIXME #2252: bounds checking float literals is deferred until trans
+
+    // Strip underscores without allocating a new String unless necessary.
+    let s2;
+    let s = if s.chars().any(|c| c == '_') {
+        s2 = s.chars().filter(|&c| c != '_').collect::<String>();
+        &s2
+    } else {
+        s
+    };
+
+    filtered_float_lit(Symbol::intern(s), suffix, diag)
+}
+
+fn integer_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>)
+                   -> Option<LitKind> {
+    // s can only be ascii, byte indexing is fine
+
+    // Strip underscores without allocating a new String unless necessary.
+    let s2;
+    let mut s = if s.chars().any(|c| c == '_') {
+        s2 = s.chars().filter(|&c| c != '_').collect::<String>();
+        &s2
+    } else {
+        s
+    };
+
+    debug!("integer_lit: {}, {:?}", s, suffix);
+
+    let mut base = 10;
+    let orig = s;
+    let mut ty = ast::LitIntType::Unsuffixed;
+
+    if s.starts_with('0') && s.len() > 1 {
+        match s.as_bytes()[1] {
+            b'x' => base = 16,
+            b'o' => base = 8,
+            b'b' => base = 2,
+            _ => { }
+        }
+    }
+
+    // 1f64 and 2f32 etc. are valid float literals.
+    if let Some(suf) = suffix {
+        if looks_like_width_suffix(&['f'], &suf.as_str()) {
+            let err = match base {
+                16 => Some("hexadecimal float literal is not supported"),
+                8 => Some("octal float literal is not supported"),
+                2 => Some("binary float literal is not supported"),
+                _ => None,
+            };
+            if let Some(err) = err {
+                err!(diag, |span, diag| {
+                    diag.struct_span_err(span, err)
+                        .span_label(span, "not supported")
+                        .emit();
+                });
+            }
+            return filtered_float_lit(Symbol::intern(s), Some(suf), diag)
+        }
+    }
+
+    if base != 10 {
+        s = &s[2..];
+    }
+
+    if let Some(suf) = suffix {
+        if suf.as_str().is_empty() {
+            err!(diag, |span, diag| diag.span_bug(span, "found empty literal suffix in Some"));
+        }
+        ty = match &*suf.as_str() {
+            "isize" => ast::LitIntType::Signed(ast::IntTy::Isize),
+            "i8"  => ast::LitIntType::Signed(ast::IntTy::I8),
+            "i16" => ast::LitIntType::Signed(ast::IntTy::I16),
+            "i32" => ast::LitIntType::Signed(ast::IntTy::I32),
+            "i64" => ast::LitIntType::Signed(ast::IntTy::I64),
+            "i128" => ast::LitIntType::Signed(ast::IntTy::I128),
+            "usize" => ast::LitIntType::Unsigned(ast::UintTy::Usize),
+            "u8"  => ast::LitIntType::Unsigned(ast::UintTy::U8),
+            "u16" => ast::LitIntType::Unsigned(ast::UintTy::U16),
+            "u32" => ast::LitIntType::Unsigned(ast::UintTy::U32),
+            "u64" => ast::LitIntType::Unsigned(ast::UintTy::U64),
+            "u128" => ast::LitIntType::Unsigned(ast::UintTy::U128),
+            suf => {
+                // i<digits> and u<digits> look like widths, so lets
+                // give an error message along those lines
+                err!(diag, |span, diag| {
+                    if looks_like_width_suffix(&['i', 'u'], suf) {
+                        let msg = format!("invalid width `{}` for integer literal", &suf[1..]);
+                        diag.struct_span_err(span, &msg)
+                            .help("valid widths are 8, 16, 32, 64 and 128")
+                            .emit();
+                    } else {
+                        let msg = format!("invalid suffix `{}` for numeric literal", suf);
+                        diag.struct_span_err(span, &msg)
+                            .span_label(span, format!("invalid suffix `{}`", suf))
+                            .help("the suffix must be one of the integral types \
+                                   (`u32`, `isize`, etc)")
+                            .emit();
+                    }
+                });
+
+                ty
+            }
+        }
+    }
+
+    debug!("integer_lit: the type is {:?}, base {:?}, the new string is {:?}, the original \
+           string was {:?}, the original suffix was {:?}", ty, base, s, orig, suffix);
+
+    Some(match u128::from_str_radix(s, base) {
+        Ok(r) => LitKind::Int(r, ty),
+        Err(_) => {
+            // small bases are lexed as if they were base 10, e.g, the string
+            // might be `0b10201`. This will cause the conversion above to fail,
+            // but these cases have errors in the lexer: we don't want to emit
+            // two errors, and we especially don't want to emit this error since
+            // it isn't necessarily true.
+            let already_errored = base < 10 &&
+                s.chars().any(|c| c.to_digit(10).map_or(false, |d| d >= base));
+
+            if !already_errored {
+                err!(diag, |span, diag| diag.span_err(span, "int literal is too large"));
+            }
+            LitKind::Int(0, ty)
+        }
+    })
+}
index 4a9a7aec6addea8e664bbd47c36ac3b0dc2a8756..0611c1d9b42a5a6dd88791c5809e6848d5b97556 100644 (file)
@@ -5,7 +5,6 @@
 use crate::source_map::{SourceMap, FilePathMapping};
 use crate::feature_gate::UnstableFeatures;
 use crate::parse::parser::Parser;
-use crate::symbol::Symbol;
 use crate::syntax::parse::parser::emit_unclosed_delims;
 use crate::tokenstream::{TokenStream, TokenTree};
 use crate::diagnostics::plugin::ErrorMap;
@@ -14,7 +13,6 @@
 use errors::{Applicability, FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
 use rustc_data_structures::sync::{Lrc, Lock};
 use syntax_pos::{Span, SourceFile, FileName, MultiSpan};
-use log::debug;
 
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use std::borrow::Cow;
 
 #[macro_use]
 pub mod parser;
-
+pub mod attr;
 pub mod lexer;
 pub mod token;
-pub mod attr;
-pub mod diagnostics;
-
-pub mod classify;
-
-pub(crate) mod unescape;
-use unescape::{unescape_str, unescape_char, unescape_byte_str, unescape_byte};
 
-pub(crate) mod unescape_error_reporting;
+crate mod classify;
+crate mod diagnostics;
+crate mod literal;
+crate mod unescape;
+crate mod unescape_error_reporting;
 
 /// Info about a parsing session.
 pub struct ParseSess {
@@ -334,284 +329,6 @@ pub fn stream_to_parser(sess: &ParseSess, stream: TokenStream) -> Parser<'_> {
     Parser::new(sess, stream, None, true, false)
 }
 
-/// Parses a string representing a raw string literal into its final form. The
-/// only operation this does is convert embedded CRLF into a single LF.
-fn raw_str_lit(lit: &str) -> String {
-    debug!("raw_str_lit: given {}", lit.escape_default());
-    let mut res = String::with_capacity(lit.len());
-
-    let mut chars = lit.chars().peekable();
-    while let Some(c) = chars.next() {
-        if c == '\r' {
-            if *chars.peek().unwrap() != '\n' {
-                panic!("lexer accepted bare CR");
-            }
-            chars.next();
-            res.push('\n');
-        } else {
-            res.push(c);
-        }
-    }
-
-    res.shrink_to_fit();
-    res
-}
-
-// check if `s` looks like i32 or u1234 etc.
-fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
-    s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit())
-}
-
-macro_rules! err {
-    ($opt_diag:expr, |$span:ident, $diag:ident| $($body:tt)*) => {
-        match $opt_diag {
-            Some(($span, $diag)) => { $($body)* }
-            None => return None,
-        }
-    }
-}
-
-crate fn lit_token(lit: token::Lit, suf: Option<Symbol>, diag: Option<(Span, &Handler)>)
-                 -> (bool /* suffix illegal? */, Option<ast::LitKind>) {
-    use ast::LitKind;
-
-    match lit {
-        token::Byte(i) => {
-            let lit_kind = match unescape_byte(&i.as_str()) {
-                Ok(c) => LitKind::Byte(c),
-                Err(_) => LitKind::Err(i),
-            };
-            (true, Some(lit_kind))
-        },
-        token::Char(i) => {
-            let lit_kind = match unescape_char(&i.as_str()) {
-                Ok(c) => LitKind::Char(c),
-                Err(_) => LitKind::Err(i),
-            };
-            (true, Some(lit_kind))
-        },
-        token::Err(i) => (true, Some(LitKind::Err(i))),
-
-        // There are some valid suffixes for integer and float literals,
-        // so all the handling is done internally.
-        token::Integer(s) => (false, integer_lit(&s.as_str(), suf, diag)),
-        token::Float(s) => (false, float_lit(&s.as_str(), suf, diag)),
-
-        token::Str_(mut sym) => {
-            // If there are no characters requiring special treatment we can
-            // reuse the symbol from the Token. Otherwise, we must generate a
-            // new symbol because the string in the LitKind is different to the
-            // string in the Token.
-            let mut has_error = false;
-            let s = &sym.as_str();
-            if s.as_bytes().iter().any(|&c| c == b'\\' || c == b'\r') {
-                let mut buf = String::with_capacity(s.len());
-                unescape_str(s, &mut |_, unescaped_char| {
-                    match unescaped_char {
-                        Ok(c) => buf.push(c),
-                        Err(_) => has_error = true,
-                    }
-                });
-                if has_error {
-                    return (true, Some(LitKind::Err(sym)));
-                }
-                sym = Symbol::intern(&buf)
-            }
-
-            (true, Some(LitKind::Str(sym, ast::StrStyle::Cooked)))
-        }
-        token::StrRaw(mut sym, n) => {
-            // Ditto.
-            let s = &sym.as_str();
-            if s.contains('\r') {
-                sym = Symbol::intern(&raw_str_lit(s));
-            }
-            (true, Some(LitKind::Str(sym, ast::StrStyle::Raw(n))))
-        }
-        token::ByteStr(i) => {
-            let s = &i.as_str();
-            let mut buf = Vec::with_capacity(s.len());
-            let mut has_error = false;
-            unescape_byte_str(s, &mut |_, unescaped_byte| {
-                match unescaped_byte {
-                    Ok(c) => buf.push(c),
-                    Err(_) => has_error = true,
-                }
-            });
-            if has_error {
-                return (true, Some(LitKind::Err(i)));
-            }
-            buf.shrink_to_fit();
-            (true, Some(LitKind::ByteStr(Lrc::new(buf))))
-        }
-        token::ByteStrRaw(i, _) => {
-            (true, Some(LitKind::ByteStr(Lrc::new(i.to_string().into_bytes()))))
-        }
-    }
-}
-
-fn filtered_float_lit(data: Symbol, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>)
-                      -> Option<ast::LitKind> {
-    debug!("filtered_float_lit: {}, {:?}", data, suffix);
-    let suffix = match suffix {
-        Some(suffix) => suffix,
-        None => return Some(ast::LitKind::FloatUnsuffixed(data)),
-    };
-
-    Some(match &*suffix.as_str() {
-        "f32" => ast::LitKind::Float(data, ast::FloatTy::F32),
-        "f64" => ast::LitKind::Float(data, ast::FloatTy::F64),
-        suf => {
-            err!(diag, |span, diag| {
-                if suf.len() >= 2 && looks_like_width_suffix(&['f'], suf) {
-                    // if it looks like a width, lets try to be helpful.
-                    let msg = format!("invalid width `{}` for float literal", &suf[1..]);
-                    diag.struct_span_err(span, &msg).help("valid widths are 32 and 64").emit()
-                } else {
-                    let msg = format!("invalid suffix `{}` for float literal", suf);
-                    diag.struct_span_err(span, &msg)
-                        .span_label(span, format!("invalid suffix `{}`", suf))
-                        .help("valid suffixes are `f32` and `f64`")
-                        .emit();
-                }
-            });
-
-            ast::LitKind::FloatUnsuffixed(data)
-        }
-    })
-}
-fn float_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>)
-                 -> Option<ast::LitKind> {
-    debug!("float_lit: {:?}, {:?}", s, suffix);
-    // FIXME #2252: bounds checking float literals is deferred until trans
-
-    // Strip underscores without allocating a new String unless necessary.
-    let s2;
-    let s = if s.chars().any(|c| c == '_') {
-        s2 = s.chars().filter(|&c| c != '_').collect::<String>();
-        &s2
-    } else {
-        s
-    };
-
-    filtered_float_lit(Symbol::intern(s), suffix, diag)
-}
-
-fn integer_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>)
-                   -> Option<ast::LitKind> {
-    // s can only be ascii, byte indexing is fine
-
-    // Strip underscores without allocating a new String unless necessary.
-    let s2;
-    let mut s = if s.chars().any(|c| c == '_') {
-        s2 = s.chars().filter(|&c| c != '_').collect::<String>();
-        &s2
-    } else {
-        s
-    };
-
-    debug!("integer_lit: {}, {:?}", s, suffix);
-
-    let mut base = 10;
-    let orig = s;
-    let mut ty = ast::LitIntType::Unsuffixed;
-
-    if s.starts_with('0') && s.len() > 1 {
-        match s.as_bytes()[1] {
-            b'x' => base = 16,
-            b'o' => base = 8,
-            b'b' => base = 2,
-            _ => { }
-        }
-    }
-
-    // 1f64 and 2f32 etc. are valid float literals.
-    if let Some(suf) = suffix {
-        if looks_like_width_suffix(&['f'], &suf.as_str()) {
-            let err = match base {
-                16 => Some("hexadecimal float literal is not supported"),
-                8 => Some("octal float literal is not supported"),
-                2 => Some("binary float literal is not supported"),
-                _ => None,
-            };
-            if let Some(err) = err {
-                err!(diag, |span, diag| {
-                    diag.struct_span_err(span, err)
-                        .span_label(span, "not supported")
-                        .emit();
-                });
-            }
-            return filtered_float_lit(Symbol::intern(s), Some(suf), diag)
-        }
-    }
-
-    if base != 10 {
-        s = &s[2..];
-    }
-
-    if let Some(suf) = suffix {
-        if suf.as_str().is_empty() {
-            err!(diag, |span, diag| diag.span_bug(span, "found empty literal suffix in Some"));
-        }
-        ty = match &*suf.as_str() {
-            "isize" => ast::LitIntType::Signed(ast::IntTy::Isize),
-            "i8"  => ast::LitIntType::Signed(ast::IntTy::I8),
-            "i16" => ast::LitIntType::Signed(ast::IntTy::I16),
-            "i32" => ast::LitIntType::Signed(ast::IntTy::I32),
-            "i64" => ast::LitIntType::Signed(ast::IntTy::I64),
-            "i128" => ast::LitIntType::Signed(ast::IntTy::I128),
-            "usize" => ast::LitIntType::Unsigned(ast::UintTy::Usize),
-            "u8"  => ast::LitIntType::Unsigned(ast::UintTy::U8),
-            "u16" => ast::LitIntType::Unsigned(ast::UintTy::U16),
-            "u32" => ast::LitIntType::Unsigned(ast::UintTy::U32),
-            "u64" => ast::LitIntType::Unsigned(ast::UintTy::U64),
-            "u128" => ast::LitIntType::Unsigned(ast::UintTy::U128),
-            suf => {
-                // i<digits> and u<digits> look like widths, so lets
-                // give an error message along those lines
-                err!(diag, |span, diag| {
-                    if looks_like_width_suffix(&['i', 'u'], suf) {
-                        let msg = format!("invalid width `{}` for integer literal", &suf[1..]);
-                        diag.struct_span_err(span, &msg)
-                            .help("valid widths are 8, 16, 32, 64 and 128")
-                            .emit();
-                    } else {
-                        let msg = format!("invalid suffix `{}` for numeric literal", suf);
-                        diag.struct_span_err(span, &msg)
-                            .span_label(span, format!("invalid suffix `{}`", suf))
-                            .help("the suffix must be one of the integral types \
-                                   (`u32`, `isize`, etc)")
-                            .emit();
-                    }
-                });
-
-                ty
-            }
-        }
-    }
-
-    debug!("integer_lit: the type is {:?}, base {:?}, the new string is {:?}, the original \
-           string was {:?}, the original suffix was {:?}", ty, base, s, orig, suffix);
-
-    Some(match u128::from_str_radix(s, base) {
-        Ok(r) => ast::LitKind::Int(r, ty),
-        Err(_) => {
-            // small bases are lexed as if they were base 10, e.g, the string
-            // might be `0b10201`. This will cause the conversion above to fail,
-            // but these cases have errors in the lexer: we don't want to emit
-            // two errors, and we especially don't want to emit this error since
-            // it isn't necessarily true.
-            let already_errored = base < 10 &&
-                s.chars().any(|c| c.to_digit(10).map_or(false, |d| d >= base));
-
-            if !already_errored {
-                err!(diag, |span, diag| diag.span_err(span, "int literal is too large"));
-            }
-            ast::LitKind::Int(0, ty)
-        }
-    })
-}
-
 /// A sequence separator.
 pub struct SeqSep {
     /// The seperator token.
@@ -674,6 +391,8 @@ fn sp(a: u32, b: u32) -> Span {
     #[test]
     fn string_to_tts_macro () {
         with_globals(|| {
+            use crate::symbol::sym;
+
             let tts: Vec<_> =
                 string_to_stream("macro_rules! zip (($a)=>($a))".to_string()).trees().collect();
             let tts: &[TokenTree] = &tts[..];
@@ -686,8 +405,8 @@ fn string_to_tts_macro () {
                     Some(&TokenTree::Token(_, token::Ident(name_zip, false))),
                     Some(&TokenTree::Delimited(_, macro_delim, ref macro_tts)),
                 )
-                if name_macro_rules.name == "macro_rules"
-                && name_zip.name == "zip" => {
+                if name_macro_rules.name == sym::macro_rules
+                && name_zip.name.as_str() == "zip" => {
                     let tts = &macro_tts.trees().collect::<Vec<_>>();
                     match (tts.len(), tts.get(0), tts.get(1), tts.get(2)) {
                         (
@@ -704,7 +423,7 @@ fn string_to_tts_macro () {
                                     Some(&TokenTree::Token(_, token::Dollar)),
                                     Some(&TokenTree::Token(_, token::Ident(ident, false))),
                                 )
-                                if first_delim == token::Paren && ident.name == "a" => {},
+                                if first_delim == token::Paren && ident.name.as_str() == "a" => {},
                                 _ => panic!("value 3: {:?} {:?}", first_delim, first_tts),
                             }
                             let tts = &second_tts.trees().collect::<Vec<_>>();
@@ -714,7 +433,7 @@ fn string_to_tts_macro () {
                                     Some(&TokenTree::Token(_, token::Dollar)),
                                     Some(&TokenTree::Token(_, token::Ident(ident, false))),
                                 )
-                                if second_delim == token::Paren && ident.name == "a" => {},
+                                if second_delim == token::Paren && ident.name.as_str() == "a" => {},
                                 _ => panic!("value 4: {:?} {:?}", second_delim, second_tts),
                             }
                         },
@@ -858,20 +577,22 @@ fn wb() -> c_int { O_WRONLY as c_int }
 
     #[test] fn crlf_doc_comments() {
         with_globals(|| {
+            use crate::symbol::sym;
+
             let sess = ParseSess::new(FilePathMapping::empty());
 
             let name_1 = FileName::Custom("crlf_source_1".to_string());
             let source = "/// doc comment\r\nfn foo() {}".to_string();
             let item = parse_item_from_source_str(name_1, source, &sess)
                 .unwrap().unwrap();
-            let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
-            assert_eq!(doc, "/// doc comment");
+            let doc = first_attr_value_str_by_name(&item.attrs, sym::doc).unwrap();
+            assert_eq!(doc.as_str(), "/// doc comment");
 
             let name_2 = FileName::Custom("crlf_source_2".to_string());
             let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
             let item = parse_item_from_source_str(name_2, source, &sess)
                 .unwrap().unwrap();
-            let docs = item.attrs.iter().filter(|a| a.path == "doc")
+            let docs = item.attrs.iter().filter(|a| a.path == sym::doc)
                         .map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>();
             let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()];
             assert_eq!(&docs[..], b);
@@ -879,8 +600,8 @@ fn wb() -> c_int { O_WRONLY as c_int }
             let name_3 = FileName::Custom("clrf_source_3".to_string());
             let source = "/** doc comment\r\n *  with CRLF */\r\nfn foo() {}".to_string();
             let item = parse_item_from_source_str(name_3, source, &sess).unwrap().unwrap();
-            let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
-            assert_eq!(doc, "/** doc comment\n *  with CRLF */");
+            let doc = first_attr_value_str_by_name(&item.attrs, sym::doc).unwrap();
+            assert_eq!(doc.as_str(), "/** doc comment\n *  with CRLF */");
         });
     }
 
index d97d1e2f0f4eec67407b05b72b662bd39dd8e6c8..2d6c8c540758322cd83924e180f78f59e99cc408 100644 (file)
@@ -15,7 +15,7 @@
 use crate::ast::{GenericParam, GenericParamKind};
 use crate::ast::GenericArg;
 use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind};
-use crate::ast::{Label, Lifetime, Lit, LitKind};
+use crate::ast::{Label, Lifetime};
 use crate::ast::{Local, LocalSource};
 use crate::ast::MacStmtStyle;
 use crate::ast::{Mac, Mac_, MacDelimiter};
@@ -35,7 +35,7 @@
 use crate::{ast, attr};
 use crate::ext::base::DummyResult;
 use crate::source_map::{self, SourceMap, Spanned, respan};
-use crate::parse::{self, SeqSep, classify, token};
+use crate::parse::{SeqSep, classify, literal, token};
 use crate::parse::lexer::{TokenAndSpan, UnmatchedBrace};
 use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
 use crate::parse::token::DelimToken;
@@ -46,7 +46,7 @@
 use crate::parse::PResult;
 use crate::ThinVec;
 use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
-use crate::symbol::{Symbol, keywords};
+use crate::symbol::{keywords, sym, Symbol};
 
 use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
 use rustc_target::spec::abi::{self, Abi};
@@ -613,7 +613,7 @@ fn token_descr(&self) -> Option<&'static str> {
         })
     }
 
-    fn this_token_descr(&self) -> String {
+    crate fn this_token_descr(&self) -> String {
         if let Some(prefix) = self.token_descr() {
             format!("{} `{}`", prefix, self.this_token_to_string())
         } else {
@@ -621,11 +621,6 @@ fn this_token_descr(&self) -> String {
         }
     }
 
-    fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> {
-        let token_str = pprust::token_to_string(t);
-        Err(self.span_fatal(self.prev_span, &format!("unexpected token: `{}`", token_str)))
-    }
-
     crate fn unexpected<T>(&mut self) -> PResult<'a, T> {
         match self.expect_one_of(&[], &[]) {
             Err(e) => Err(e),
@@ -1109,43 +1104,7 @@ fn expect_or(&mut self) -> PResult<'a, ()> {
     }
 
     fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option<ast::Name>) {
-        match suffix {
-            None => {/* everything ok */}
-            Some(suf) => {
-                let text = suf.as_str();
-                if text.is_empty() {
-                    self.span_bug(sp, "found empty literal suffix in Some")
-                }
-                let mut err = if kind == "a tuple index" &&
-                    ["i32", "u32", "isize", "usize"].contains(&text.to_string().as_str())
-                {
-                    // #59553: warn instead of reject out of hand to allow the fix to percolate
-                    // through the ecosystem when people fix their macros
-                    let mut err = self.struct_span_warn(
-                        sp,
-                        &format!("suffixes on {} are invalid", kind),
-                    );
-                    err.note(&format!(
-                        "`{}` is *temporarily* accepted on tuple index fields as it was \
-                         incorrectly accepted on stable for a few releases",
-                        text,
-                    ));
-                    err.help(
-                        "on proc macros, you'll want to use `syn::Index::from` or \
-                         `proc_macro::Literal::*_unsuffixed` for code that will desugar \
-                         to tuple field access",
-                    );
-                    err.note(
-                        "for more context, see https://github.com/rust-lang/rust/issues/60210",
-                    );
-                    err
-                } else {
-                    self.struct_span_err(sp, &format!("suffixes on {} are invalid", kind))
-                };
-                err.span_label(sp, format!("invalid suffix `{}`", text));
-                err.emit();
-            }
-        }
+        literal::expect_no_suffix(sp, &self.sess.span_diagnostic, kind, suffix)
     }
 
     /// Attempts to consume a `<`. If `<<` is seen, replaces it with a single
@@ -1423,7 +1382,7 @@ pub fn look_ahead<R, F>(&self, dist: usize, f: F) -> R where
         })
     }
 
-    fn look_ahead_span(&self, dist: usize) -> Span {
+    crate fn look_ahead_span(&self, dist: usize) -> Span {
         if dist == 0 {
             return self.span
         }
@@ -1452,9 +1411,6 @@ fn span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
     crate fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
         self.sess.span_diagnostic.struct_span_err(sp, m)
     }
-    fn struct_span_warn<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
-        self.sess.span_diagnostic.struct_span_warn(sp, m)
-    }
     crate fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> ! {
         self.sess.span_diagnostic.span_bug(sp, m)
     }
@@ -1877,7 +1833,7 @@ fn parse_ptr(&mut self) -> PResult<'a, MutTy> {
         Ok(MutTy { ty: t, mutbl: mutbl })
     }
 
-    fn is_named_argument(&mut self) -> bool {
+    fn is_named_argument(&self) -> bool {
         let offset = match self.token {
             token::Interpolated(ref nt) => match **nt {
                 token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
@@ -1925,8 +1881,6 @@ fn eat_incorrect_doc_comment(&mut self, applied_to: &str) {
     /// This version of parse arg doesn't necessarily require identifier names.
     fn parse_arg_general(&mut self, require_name: bool, is_trait_item: bool,
                          allow_c_variadic: bool) -> PResult<'a, Arg> {
-        maybe_whole!(self, NtArg, |x| x);
-
         if let Ok(Some(_)) = self.parse_self_arg() {
             let mut err = self.struct_span_err(self.prev_span,
                 "unexpected `self` argument in function");
@@ -2069,88 +2023,6 @@ fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<'a, Option<P<ast::Expr>
         }
     }
 
-    /// Matches `token_lit = LIT_INTEGER | ...`.
-    fn parse_lit_token(&mut self) -> PResult<'a, LitKind> {
-        let out = match self.token {
-            token::Interpolated(ref nt) => match **nt {
-                token::NtExpr(ref v) | token::NtLiteral(ref v) => match v.node {
-                    ExprKind::Lit(ref lit) => { lit.node.clone() }
-                    _ => { return self.unexpected_last(&self.token); }
-                },
-                _ => { return self.unexpected_last(&self.token); }
-            },
-            token::Literal(lit, suf) => {
-                let diag = Some((self.span, &self.sess.span_diagnostic));
-                let (suffix_illegal, result) = parse::lit_token(lit, suf, diag);
-
-                if suffix_illegal {
-                    let sp = self.span;
-                    self.expect_no_suffix(sp, &format!("a {}", lit.literal_name()), suf)
-                }
-
-                result.unwrap()
-            }
-            token::Dot if self.look_ahead(1, |t| match t {
-                token::Literal(parse::token::Lit::Integer(_) , _) => true,
-                _ => false,
-            }) => { // recover from `let x = .4;`
-                let lo = self.span;
-                self.bump();
-                if let token::Literal(
-                    parse::token::Lit::Integer(val),
-                    suffix,
-                ) = self.token {
-                    let suffix = suffix.and_then(|s| {
-                        let s = s.as_str();
-                        if s == "f32" {
-                            Some("f32")
-                        } else if s == "f64" {
-                            Some("f64")
-                        } else {
-                            None
-                        }
-                    }).unwrap_or("");
-                    self.bump();
-                    let sp = lo.to(self.prev_span);
-                    let mut err = self.diagnostic()
-                        .struct_span_err(sp, "float literals must have an integer part");
-                    err.span_suggestion(
-                        sp,
-                        "must have an integer part",
-                        format!("0.{}{}", val, suffix),
-                        Applicability::MachineApplicable,
-                    );
-                    err.emit();
-                    return Ok(match suffix {
-                        "f32" => ast::LitKind::Float(val, ast::FloatTy::F32),
-                        "f64" => ast::LitKind::Float(val, ast::FloatTy::F64),
-                        _ => ast::LitKind::FloatUnsuffixed(val),
-                    });
-                } else {
-                    unreachable!();
-                };
-            }
-            _ => { return self.unexpected_last(&self.token); }
-        };
-
-        self.bump();
-        Ok(out)
-    }
-
-    /// Matches `lit = true | false | token_lit`.
-    crate fn parse_lit(&mut self) -> PResult<'a, Lit> {
-        let lo = self.span;
-        let lit = if self.eat_keyword(keywords::True) {
-            LitKind::Bool(true)
-        } else if self.eat_keyword(keywords::False) {
-            LitKind::Bool(false)
-        } else {
-            let lit = self.parse_lit_token()?;
-            lit
-        };
-        Ok(source_map::Spanned { node: lit, span: lo.to(self.prev_span) })
-    }
-
     /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`).
     crate fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
         maybe_whole_expr!(self);
@@ -2471,27 +2343,27 @@ fn parse_field(&mut self) -> PResult<'a, Field> {
         })
     }
 
-    fn mk_expr(&mut self, span: Span, node: ExprKind, attrs: ThinVec<Attribute>) -> P<Expr> {
+    fn mk_expr(&self, span: Span, node: ExprKind, attrs: ThinVec<Attribute>) -> P<Expr> {
         P(Expr { node, span, attrs, id: ast::DUMMY_NODE_ID })
     }
 
-    fn mk_unary(&mut self, unop: ast::UnOp, expr: P<Expr>) -> ast::ExprKind {
+    fn mk_unary(&self, unop: ast::UnOp, expr: P<Expr>) -> ast::ExprKind {
         ExprKind::Unary(unop, expr)
     }
 
-    fn mk_binary(&mut self, binop: ast::BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ast::ExprKind {
+    fn mk_binary(&self, binop: ast::BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ast::ExprKind {
         ExprKind::Binary(binop, lhs, rhs)
     }
 
-    fn mk_call(&mut self, f: P<Expr>, args: Vec<P<Expr>>) -> ast::ExprKind {
+    fn mk_call(&self, f: P<Expr>, args: Vec<P<Expr>>) -> ast::ExprKind {
         ExprKind::Call(f, args)
     }
 
-    fn mk_index(&mut self, expr: P<Expr>, idx: P<Expr>) -> ast::ExprKind {
+    fn mk_index(&self, expr: P<Expr>, idx: P<Expr>) -> ast::ExprKind {
         ExprKind::Index(expr, idx)
     }
 
-    fn mk_range(&mut self,
+    fn mk_range(&self,
                     start: Option<P<Expr>>,
                     end: Option<P<Expr>>,
                     limits: RangeLimits)
@@ -2503,7 +2375,7 @@ fn mk_range(&mut self,
         }
     }
 
-    fn mk_assign_op(&mut self, binop: ast::BinOp,
+    fn mk_assign_op(&self, binop: ast::BinOp,
                         lhs: P<Expr>, rhs: P<Expr>) -> ast::ExprKind {
         ExprKind::AssignOp(binop, lhs, rhs)
     }
@@ -2643,13 +2515,12 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
                     hi = path.span;
                     return Ok(self.mk_expr(lo.to(hi), ExprKind::Path(Some(qself), path), attrs));
                 }
-                if self.span.rust_2018() && self.check_keyword(keywords::Async)
-                {
-                    if self.is_async_block() { // check for `async {` and `async move {`
-                        return self.parse_async_block(attrs);
+                if self.span.rust_2018() && self.check_keyword(keywords::Async) {
+                    return if self.is_async_block() { // check for `async {` and `async move {`
+                        self.parse_async_block(attrs)
                     } else {
-                        return self.parse_lambda_expr(attrs);
-                    }
+                        self.parse_lambda_expr(attrs)
+                    };
                 }
                 if self.check_keyword(keywords::Move) || self.check_keyword(keywords::Static) {
                     return self.parse_lambda_expr(attrs);
@@ -3574,7 +3445,8 @@ fn parse_assoc_expr_with(&mut self,
             } else {
                 self.restrictions
             };
-            if op.precedence() < min_prec {
+            let prec = op.precedence();
+            if prec < min_prec {
                 break;
             }
             // Check for deprecated `...` syntax
@@ -3615,8 +3487,7 @@ fn parse_assoc_expr_with(&mut self,
                 // We have 2 alternatives here: `x..y`/`x..=y` and `x..`/`x..=` The other
                 // two variants are handled with `parse_prefix_range_expr` call above.
                 let rhs = if self.is_at_start_of_range_notation_rhs() {
-                    Some(self.parse_assoc_expr_with(op.precedence() + 1,
-                                                    LhsExpr::NotYetParsed)?)
+                    Some(self.parse_assoc_expr_with(prec + 1, LhsExpr::NotYetParsed)?)
                 } else {
                     None
                 };
@@ -3636,28 +3507,18 @@ fn parse_assoc_expr_with(&mut self,
                 break
             }
 
-            let rhs = match op.fixity() {
-                Fixity::Right => self.with_res(
-                    restrictions - Restrictions::STMT_EXPR,
-                    |this| {
-                        this.parse_assoc_expr_with(op.precedence(),
-                            LhsExpr::NotYetParsed)
-                }),
-                Fixity::Left => self.with_res(
-                    restrictions - Restrictions::STMT_EXPR,
-                    |this| {
-                        this.parse_assoc_expr_with(op.precedence() + 1,
-                            LhsExpr::NotYetParsed)
-                }),
+            let fixity = op.fixity();
+            let prec_adjustment = match fixity {
+                Fixity::Right => 0,
+                Fixity::Left => 1,
                 // We currently have no non-associative operators that are not handled above by
                 // the special cases. The code is here only for future convenience.
-                Fixity::None => self.with_res(
-                    restrictions - Restrictions::STMT_EXPR,
-                    |this| {
-                        this.parse_assoc_expr_with(op.precedence() + 1,
-                            LhsExpr::NotYetParsed)
-                }),
-            }?;
+                Fixity::None => 1,
+            };
+            let rhs = self.with_res(
+                restrictions - Restrictions::STMT_EXPR,
+                |this| this.parse_assoc_expr_with(prec + prec_adjustment, LhsExpr::NotYetParsed)
+            )?;
 
             // Make sure that the span of the parent node is larger than the span of lhs and rhs,
             // including the attributes.
@@ -3703,7 +3564,7 @@ fn parse_assoc_expr_with(&mut self,
                 }
             };
 
-            if op.fixity() == Fixity::None { break }
+            if let Fixity::None = fixity { break }
         }
         Ok(lhs)
     }
@@ -3840,7 +3701,7 @@ fn parse_assoc_op_cast(&mut self, lhs: P<Expr>, lhs_span: Span,
     /// Produce an error if comparison operators are chained (RFC #558).
     /// We only need to check lhs, not rhs, because all comparison ops
     /// have same precedence and are left-associative
-    fn check_no_chained_comparison(&mut self, lhs: &Expr, outer_op: &AssocOp) {
+    fn check_no_chained_comparison(&self, lhs: &Expr, outer_op: &AssocOp) {
         debug_assert!(outer_op.is_comparison(),
                       "check_no_chained_comparison: {:?} is not comparison",
                       outer_op);
@@ -4179,8 +4040,6 @@ fn parse_match_expr(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<E
     }
 
     crate fn parse_arm(&mut self) -> PResult<'a, Arm> {
-        maybe_whole!(self, NtArm, |x| x);
-
         let attrs = self.parse_outer_attributes()?;
         let pats = self.parse_pats()?;
         let guard = if self.eat_keyword(keywords::If) {
@@ -5137,7 +4996,7 @@ fn parse_stmt_(&mut self, macro_legacy_warnings: bool) -> Option<Stmt> {
         })
     }
 
-    fn is_async_block(&mut self) -> bool {
+    fn is_async_block(&self) -> bool {
         self.token.is_keyword(keywords::Async) &&
         (
             ( // `async move {`
@@ -5149,19 +5008,19 @@ fn is_async_block(&mut self) -> bool {
         )
     }
 
-    fn is_async_fn(&mut self) -> bool {
+    fn is_async_fn(&self) -> bool {
         self.token.is_keyword(keywords::Async) &&
             self.look_ahead(1, |t| t.is_keyword(keywords::Fn))
     }
 
-    fn is_do_catch_block(&mut self) -> bool {
+    fn is_do_catch_block(&self) -> bool {
         self.token.is_keyword(keywords::Do) &&
         self.look_ahead(1, |t| t.is_keyword(keywords::Catch)) &&
         self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace)) &&
         !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
     }
 
-    fn is_try_block(&mut self) -> bool {
+    fn is_try_block(&self) -> bool {
         self.token.is_keyword(keywords::Try) &&
         self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) &&
         self.span.rust_2018() &&
@@ -5183,7 +5042,7 @@ fn is_existential_type_decl(&self) -> bool {
         self.look_ahead(1, |t| t.is_keyword(keywords::Type))
     }
 
-    fn is_auto_trait_item(&mut self) -> bool {
+    fn is_auto_trait_item(&self) -> bool {
         // auto trait
         (self.token.is_keyword(keywords::Auto)
             && self.look_ahead(1, |t| t.is_keyword(keywords::Trait)))
@@ -5225,7 +5084,7 @@ fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility, lo: Span)
 
                 (ident, ast::MacroDef { tokens: tokens.into(), legacy: false })
             }
-            token::Ident(ident, _) if ident.name == "macro_rules" &&
+            token::Ident(ident, _) if ident.name == sym::macro_rules &&
                                    self.look_ahead(1, |t| *t == token::Not) => {
                 let prev_span = self.prev_span;
                 self.complain_if_pub_macro(&vis.node, prev_span);
@@ -5445,7 +5304,7 @@ fn parse_stmt_without_recovery(&mut self,
     }
 
     /// Checks if this expression is a successfully parsed statement.
-    fn expr_is_complete(&mut self, e: &Expr) -> bool {
+    fn expr_is_complete(&self, e: &Expr) -> bool {
         self.restrictions.contains(Restrictions::STMT_EXPR) &&
             !classify::expr_requires_semi_to_be_stmt(e)
     }
@@ -5915,8 +5774,6 @@ fn parse_const_param(&mut self, preceding_attrs: Vec<Attribute>) -> PResult<'a,
     ///                  | ( < lifetimes , typaramseq ( , )? > )
     /// where   typaramseq = ( typaram ) | ( typaram , typaramseq )
     fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
-        maybe_whole!(self, NtGenerics, |x| x);
-
         let span_lo = self.span;
         if self.eat_lt() {
             let params = self.parse_generic_params()?;
@@ -6169,8 +6026,6 @@ fn parse_generic_args(&mut self) -> PResult<'a, (Vec<GenericArg>, Vec<TypeBindin
     /// where T : Trait<U, V> + 'b, 'a : 'b
     /// ```
     fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> {
-        maybe_whole!(self, NtWhereClause, |x| x);
-
         let mut where_clause = WhereClause {
             id: ast::DUMMY_NODE_ID,
             predicates: Vec::new(),
@@ -6517,7 +6372,7 @@ fn parse_fn_header(&mut self) -> PResult<'a, (Ident, ast::Generics)> {
         Ok((id, generics))
     }
 
-    fn mk_item(&mut self, span: Span, ident: Ident, node: ItemKind, vis: Visibility,
+    fn mk_item(&self, span: Span, ident: Ident, node: ItemKind, vis: Visibility,
                attrs: Vec<Attribute>) -> P<Item> {
         P(Item {
             ident,
@@ -6549,7 +6404,7 @@ fn parse_item_fn(&mut self,
 
     /// Returns `true` if we are looking at `const ID`
     /// (returns `false` for things like `const fn`, etc.).
-    fn is_const_item(&mut self) -> bool {
+    fn is_const_item(&self) -> bool {
         self.token.is_keyword(keywords::Const) &&
             !self.look_ahead(1, |t| t.is_keyword(keywords::Fn)) &&
             !self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe))
@@ -6657,7 +6512,7 @@ fn parse_impl_item_(&mut self,
         })
     }
 
-    fn complain_if_pub_macro(&mut self, vis: &VisibilityKind, sp: Span) {
+    fn complain_if_pub_macro(&self, vis: &VisibilityKind, sp: Span) {
         match *vis {
             VisibilityKind::Inherited => {}
             _ => {
@@ -6686,7 +6541,7 @@ fn complain_if_pub_macro(&mut self, vis: &VisibilityKind, sp: Span) {
         }
     }
 
-    fn missing_assoc_item_kind_err(&mut self, item_type: &str, prev_span: Span)
+    fn missing_assoc_item_kind_err(&self, item_type: &str, prev_span: Span)
                                    -> DiagnosticBuilder<'a>
     {
         let expected_kinds = if item_type == "extern" {
@@ -7389,7 +7244,7 @@ fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo>
     }
 
     fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
-        if let Some(path) = attr::first_attr_value_str_by_name(attrs, "path") {
+        if let Some(path) = attr::first_attr_value_str_by_name(attrs, sym::path) {
             self.directory.path.to_mut().push(&path.as_str());
             self.directory.ownership = DirectoryOwnership::Owned { relative: None };
         } else {
@@ -7409,7 +7264,7 @@ fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
     }
 
     pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> {
-        if let Some(s) = attr::first_attr_value_str_by_name(attrs, "path") {
+        if let Some(s) = attr::first_attr_value_str_by_name(attrs, sym::path) {
             let s = s.as_str();
 
             // On windows, the base path might have the form
index fd7a39c576daa79407a4650264f284bdd7490fa5..049fb6cb78b84f241bc5144ae4771b2c6b5de822 100644 (file)
@@ -61,6 +61,7 @@ pub fn is_empty(self) -> bool {
 
 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
 pub enum Lit {
+    Bool(ast::Name), // AST only, must never appear in a `Token`
     Byte(ast::Name),
     Char(ast::Name),
     Err(ast::Name),
@@ -72,9 +73,13 @@ pub enum Lit {
     ByteStrRaw(ast::Name, u16), /* raw byte str delimited by n hash symbols */
 }
 
+#[cfg(target_arch = "x86_64")]
+static_assert!(MEM_SIZE_OF_LIT: mem::size_of::<Lit>() == 8);
+
 impl Lit {
     crate fn literal_name(&self) -> &'static str {
         match *self {
+            Bool(_) => panic!("literal token contains `Lit::Bool`"),
             Byte(_) => "byte literal",
             Char(_) => "char literal",
             Err(_) => "invalid literal",
@@ -85,6 +90,13 @@ impl Lit {
         }
     }
 
+    crate fn may_have_suffix(&self) -> bool {
+        match *self {
+            Integer(..) | Float(..) => true,
+            _ => false,
+        }
+    }
+
     // See comments in `Nonterminal::to_tokenstream` for why we care about
     // *probably* equal here rather than actual equality
     fn probably_equal_for_proc_macro(&self, other: &Lit) -> bool {
@@ -585,14 +597,12 @@ pub enum Nonterminal {
     NtPath(ast::Path),
     NtVis(ast::Visibility),
     NtTT(TokenTree),
-    // These are not exposed to macros, but are used by quasiquote.
-    NtArm(ast::Arm),
-    NtImplItem(ast::ImplItem),
+    // Used only for passing items to proc macro attributes (they are not
+    // strictly necessary for that, `Annotatable` can be converted into
+    // tokens directly, but doing that naively regresses pretty-printing).
     NtTraitItem(ast::TraitItem),
+    NtImplItem(ast::ImplItem),
     NtForeignItem(ast::ForeignItem),
-    NtGenerics(ast::Generics),
-    NtWhereClause(ast::WhereClause),
-    NtArg(ast::Arg),
 }
 
 impl PartialEq for Nonterminal {
@@ -625,13 +635,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             NtMeta(..) => f.pad("NtMeta(..)"),
             NtPath(..) => f.pad("NtPath(..)"),
             NtTT(..) => f.pad("NtTT(..)"),
-            NtArm(..) => f.pad("NtArm(..)"),
             NtImplItem(..) => f.pad("NtImplItem(..)"),
             NtTraitItem(..) => f.pad("NtTraitItem(..)"),
             NtForeignItem(..) => f.pad("NtForeignItem(..)"),
-            NtGenerics(..) => f.pad("NtGenerics(..)"),
-            NtWhereClause(..) => f.pad("NtWhereClause(..)"),
-            NtArg(..) => f.pad("NtArg(..)"),
             NtVis(..) => f.pad("NtVis(..)"),
             NtLifetime(..) => f.pad("NtLifetime(..)"),
         }
index 682621d40ab6583dfd2f2439c8d2d890b0eadc35..86db7a673d471afb105089d2d4e9541029d790a8 100644 (file)
 use syntax_pos::{self, BytePos};
 use syntax_pos::{DUMMY_SP, FileName};
 
-use std::ascii;
 use std::borrow::Cow;
 use std::io::{self, Write, Read};
-use std::iter::Peekable;
 use std::vec;
 
 pub enum AnnNode<'a> {
@@ -49,8 +47,7 @@ impl PpAnn for NoAnn {}
 pub struct State<'a> {
     pub s: pp::Printer<'a>,
     cm: Option<&'a SourceMap>,
-    comments: Option<Vec<comments::Comment> >,
-    literals: Peekable<vec::IntoIter<comments::Literal>>,
+    comments: Option<Vec<comments::Comment>>,
     cur_cmnt: usize,
     boxes: Vec<pp::Breaks>,
     ann: &'a (dyn PpAnn+'a),
@@ -62,7 +59,6 @@ fn rust_printer<'a>(writer: Box<dyn Write+'a>, ann: &'a dyn PpAnn) -> State<'a>
         s: pp::mk_printer(writer, DEFAULT_COLUMNS),
         cm: None,
         comments: None,
-        literals: vec![].into_iter().peekable(),
         cur_cmnt: 0,
         boxes: Vec::new(),
         ann,
@@ -75,8 +71,7 @@ fn rust_printer<'a>(writer: Box<dyn Write+'a>, ann: &'a dyn PpAnn) -> State<'a>
 pub const DEFAULT_COLUMNS: usize = 78;
 
 /// Requires you to pass an input filename and reader so that
-/// it can scan the input text for comments and literals to
-/// copy forward.
+/// it can scan the input text for comments to copy forward.
 pub fn print_crate<'a>(cm: &'a SourceMap,
                        sess: &ParseSess,
                        krate: &ast::Crate,
@@ -118,36 +113,23 @@ pub fn new_from_input(cm: &'a SourceMap,
                           out: Box<dyn Write+'a>,
                           ann: &'a dyn PpAnn,
                           is_expanded: bool) -> State<'a> {
-        let (cmnts, lits) = comments::gather_comments_and_literals(sess, filename, input);
-
-        State::new(
-            cm,
-            out,
-            ann,
-            Some(cmnts),
-            // If the code is post expansion, don't use the table of
-            // literals, since it doesn't correspond with the literals
-            // in the AST anymore.
-            if is_expanded { None } else { Some(lits) },
-            is_expanded
-        )
+        let comments = comments::gather_comments(sess, filename, input);
+        State::new(cm, out, ann, Some(comments), is_expanded)
     }
 
     pub fn new(cm: &'a SourceMap,
                out: Box<dyn Write+'a>,
                ann: &'a dyn PpAnn,
                comments: Option<Vec<comments::Comment>>,
-               literals: Option<Vec<comments::Literal>>,
                is_expanded: bool) -> State<'a> {
         State {
             s: pp::mk_printer(out, DEFAULT_COLUMNS),
             cm: Some(cm),
             comments,
-            literals: literals.unwrap_or_default().into_iter().peekable(),
             cur_cmnt: 0,
             boxes: Vec::new(),
             ann,
-            is_expanded: is_expanded
+            is_expanded,
         }
     }
 }
@@ -180,6 +162,31 @@ fn binop_to_string(op: BinOpToken) -> &'static str {
     }
 }
 
+pub fn literal_to_string(lit: token::Lit, suffix: Option<ast::Name>) -> String {
+    let mut out = match lit {
+        token::Byte(b)           => format!("b'{}'", b),
+        token::Char(c)           => format!("'{}'", c),
+        token::Err(c)            => format!("'{}'", c),
+        token::Bool(c)           |
+        token::Float(c)          |
+        token::Integer(c)        => c.to_string(),
+        token::Str_(s)           => format!("\"{}\"", s),
+        token::StrRaw(s, n)      => format!("r{delim}\"{string}\"{delim}",
+                                            delim="#".repeat(n as usize),
+                                            string=s),
+        token::ByteStr(v)        => format!("b\"{}\"", v),
+        token::ByteStrRaw(s, n)  => format!("br{delim}\"{string}\"{delim}",
+                                            delim="#".repeat(n as usize),
+                                            string=s),
+    };
+
+    if let Some(suffix) = suffix {
+        out.push_str(&suffix.as_str())
+    }
+
+    out
+}
+
 pub fn token_to_string(tok: &Token) -> String {
     match *tok {
         token::Eq                   => "=".to_string(),
@@ -223,29 +230,7 @@ pub fn token_to_string(tok: &Token) -> String {
         token::SingleQuote          => "'".to_string(),
 
         /* Literals */
-        token::Literal(lit, suf) => {
-            let mut out = match lit {
-                token::Byte(b)           => format!("b'{}'", b),
-                token::Char(c)           => format!("'{}'", c),
-                token::Err(c)            => format!("'{}'", c),
-                token::Float(c)          |
-                token::Integer(c)        => c.to_string(),
-                token::Str_(s)           => format!("\"{}\"", s),
-                token::StrRaw(s, n)      => format!("r{delim}\"{string}\"{delim}",
-                                                    delim="#".repeat(n as usize),
-                                                    string=s),
-                token::ByteStr(v)         => format!("b\"{}\"", v),
-                token::ByteStrRaw(s, n)   => format!("br{delim}\"{string}\"{delim}",
-                                                    delim="#".repeat(n as usize),
-                                                    string=s),
-            };
-
-            if let Some(s) = suf {
-                out.push_str(&s.as_str())
-            }
-
-            out
-        }
+        token::Literal(lit, suf) => literal_to_string(lit, suf),
 
         /* Name components */
         token::Ident(s, false)      => s.to_string(),
@@ -278,12 +263,8 @@ pub fn nonterminal_to_string(nt: &Nonterminal) -> String {
         token::NtLifetime(e)        => ident_to_string(e),
         token::NtLiteral(ref e)     => expr_to_string(e),
         token::NtTT(ref tree)       => tt_to_string(tree.clone()),
-        token::NtArm(ref e)         => arm_to_string(e),
         token::NtImplItem(ref e)    => impl_item_to_string(e),
         token::NtTraitItem(ref e)   => trait_item_to_string(e),
-        token::NtGenerics(ref e)    => generic_params_to_string(&e.params),
-        token::NtWhereClause(ref e) => where_clause_to_string(e),
-        token::NtArg(ref e)         => arg_to_string(e),
         token::NtVis(ref e)         => vis_to_string(e),
         token::NtForeignItem(ref e) => foreign_item_to_string(e),
     }
@@ -438,8 +419,6 @@ pub trait PrintState<'a> {
     fn boxes(&mut self) -> &mut Vec<pp::Breaks>;
     fn comments(&mut self) -> &mut Option<Vec<comments::Comment>>;
     fn cur_cmnt(&mut self) -> &mut usize;
-    fn cur_lit(&mut self) -> Option<&comments::Literal>;
-    fn bump_lit(&mut self) -> Option<comments::Literal>;
 
     fn word_space<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
         self.writer().word(w)?;
@@ -504,21 +483,6 @@ fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()>
         self.end()
     }
 
-    fn next_lit(&mut self, pos: BytePos) -> Option<comments::Literal> {
-        while let Some(ltrl) = self.cur_lit().cloned() {
-            if ltrl.pos > pos { break; }
-
-            // we don't need the value here since we're forced to clone cur_lit
-            // due to lack of NLL.
-            self.bump_lit();
-            if ltrl.pos == pos {
-                return Some(ltrl);
-            }
-        }
-
-        None
-    }
-
     fn maybe_print_comment(&mut self, pos: BytePos) -> io::Result<()> {
         while let Some(ref cmnt) = self.next_comment() {
             if cmnt.pos < pos {
@@ -606,60 +570,7 @@ fn next_comment(&mut self) -> Option<comments::Comment> {
 
     fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> {
         self.maybe_print_comment(lit.span.lo())?;
-        if let Some(ltrl) = self.next_lit(lit.span.lo()) {
-            return self.writer().word(ltrl.lit.clone());
-        }
-        match lit.node {
-            ast::LitKind::Str(st, style) => self.print_string(&st.as_str(), style),
-            ast::LitKind::Err(st) => {
-                let st = st.as_str().escape_debug().to_string();
-                let mut res = String::with_capacity(st.len() + 2);
-                res.push('\'');
-                res.push_str(&st);
-                res.push('\'');
-                self.writer().word(res)
-            }
-            ast::LitKind::Byte(byte) => {
-                let mut res = String::from("b'");
-                res.extend(ascii::escape_default(byte).map(|c| c as char));
-                res.push('\'');
-                self.writer().word(res)
-            }
-            ast::LitKind::Char(ch) => {
-                let mut res = String::from("'");
-                res.extend(ch.escape_default());
-                res.push('\'');
-                self.writer().word(res)
-            }
-            ast::LitKind::Int(i, t) => {
-                match t {
-                    ast::LitIntType::Signed(st) => {
-                        self.writer().word(st.val_to_string(i as i128))
-                    }
-                    ast::LitIntType::Unsigned(ut) => {
-                        self.writer().word(ut.val_to_string(i))
-                    }
-                    ast::LitIntType::Unsuffixed => {
-                        self.writer().word(i.to_string())
-                    }
-                }
-            }
-            ast::LitKind::Float(ref f, t) => {
-                self.writer().word(format!("{}{}", &f, t.ty_to_string()))
-            }
-            ast::LitKind::FloatUnsuffixed(ref f) => self.writer().word(f.as_str().to_string()),
-            ast::LitKind::Bool(val) => {
-                if val { self.writer().word("true") } else { self.writer().word("false") }
-            }
-            ast::LitKind::ByteStr(ref v) => {
-                let mut escaped: String = String::new();
-                for &ch in v.iter() {
-                    escaped.extend(ascii::escape_default(ch)
-                                         .map(|c| c as char));
-                }
-                self.writer().word(format!("b\"{}\"", escaped))
-            }
-        }
+        self.writer().word(literal_to_string(lit.token, lit.suffix))
     }
 
     fn print_string(&mut self, st: &str,
@@ -880,14 +791,6 @@ fn comments(&mut self) -> &mut Option<Vec<comments::Comment>> {
     fn cur_cmnt(&mut self) -> &mut usize {
         &mut self.cur_cmnt
     }
-
-    fn cur_lit(&mut self) -> Option<&comments::Literal> {
-        self.literals.peek()
-    }
-
-    fn bump_lit(&mut self) -> Option<comments::Literal> {
-        self.literals.next()
-    }
 }
 
 impl<'a> State<'a> {
index b9758bd655c155ea92a15d048c7ae0e3515fdbac..f08fdcc6fb53cd9a58b898b78a9000a9ece7532b 100644 (file)
@@ -2,7 +2,7 @@
 use crate::attr;
 use crate::edition::Edition;
 use crate::ext::hygiene::{Mark, SyntaxContext};
-use crate::symbol::{Symbol, keywords};
+use crate::symbol::{Symbol, keywords, sym};
 use crate::source_map::{ExpnInfo, MacroAttribute, dummy_spanned, hygiene, respan};
 use crate::ptr::P;
 use crate::tokenstream::TokenStream;
@@ -35,6 +35,9 @@ pub fn injected_crate_name() -> Option<&'static str> {
 }
 
 thread_local! {
+    // A `Symbol` might make more sense here, but it doesn't work, probably for
+    // reasons relating to the use of thread-local storage for the Symbol
+    // interner.
     static INJECTED_CRATE_NAME: Cell<Option<&'static str>> = Cell::new(None);
 }
 
@@ -46,10 +49,10 @@ pub fn maybe_inject_crates_ref(
     let rust_2018 = edition >= Edition::Edition2018;
 
     // the first name in this list is the crate name of the crate with the prelude
-    let names: &[&str] = if attr::contains_name(&krate.attrs, "no_core") {
+    let names: &[&str] = if attr::contains_name(&krate.attrs, sym::no_core) {
         return krate;
-    } else if attr::contains_name(&krate.attrs, "no_std") {
-        if attr::contains_name(&krate.attrs, "compiler_builtins") {
+    } else if attr::contains_name(&krate.attrs, sym::no_std) {
+        if attr::contains_name(&krate.attrs, sym::compiler_builtins) {
             &["core"]
         } else {
             &["core", "compiler_builtins"]
index 03d0eff266e75845d437e233c97e3b249eed81e4..21bc236d00e6b805dd62ec546460598d0c90849b 100644 (file)
@@ -29,7 +29,7 @@
 use crate::print::pprust;
 use crate::ast::{self, Ident};
 use crate::ptr::P;
-use crate::symbol::{self, Symbol, keywords};
+use crate::symbol::{self, Symbol, keywords, sym};
 use crate::ThinVec;
 
 struct Test {
@@ -65,8 +65,7 @@ pub fn modify_for_testing(sess: &ParseSess,
     // unconditional, so that the attribute is still marked as used in
     // non-test builds.
     let reexport_test_harness_main =
-        attr::first_attr_value_str_by_name(&krate.attrs,
-                                           "reexport_test_harness_main");
+        attr::first_attr_value_str_by_name(&krate.attrs, sym::reexport_test_harness_main);
 
     // Do this here so that the test_runner crate attribute gets marked as used
     // even in non-test builds
@@ -185,7 +184,7 @@ impl MutVisitor for EntryPointCleaner {
                         ident,
                         attrs: attrs.into_iter()
                             .filter(|attr| {
-                                !attr.check_name("main") && !attr.check_name("start")
+                                !attr.check_name(sym::main) && !attr.check_name(sym::start)
                             })
                             .chain(iter::once(allow_dead_code))
                             .collect(),
@@ -273,7 +272,8 @@ fn generate_test_harness(sess: &ParseSess,
         test_cases: Vec::new(),
         reexport_test_harness_main,
         // N.B., doesn't consider the value of `--crate-name` passed on the command line.
-        is_libtest: attr::find_crate_name(&krate.attrs).map(|s| s == "test").unwrap_or(false),
+        is_libtest: attr::find_crate_name(&krate.attrs)
+            .map(|s| s == sym::test).unwrap_or(false),
         toplevel_reexport: None,
         ctxt: SyntaxContext::empty().apply_mark(mark),
         features,
@@ -428,11 +428,11 @@ fn visible_path(cx: &TestCtxt<'_>, path: &[Ident]) -> Vec<Ident>{
 }
 
 fn is_test_case(i: &ast::Item) -> bool {
-    attr::contains_name(&i.attrs, "rustc_test_marker")
+    attr::contains_name(&i.attrs, sym::rustc_test_marker)
 }
 
 fn get_test_runner(sd: &errors::Handler, krate: &ast::Crate) -> Option<ast::Path> {
-    let test_attr = attr::find_by_name(&krate.attrs, "test_runner")?;
+    let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?;
     test_attr.meta_item_list().map(|meta_list| {
         if meta_list.len() != 1 {
             sd.span_fatal(test_attr.span,
index 8edd0e1ae3884239b21a1b437cd0e1323108d22f..b8e89c3ecf8762191b77c84cd88ca3416f98a956 100644 (file)
@@ -11,7 +11,7 @@
 use syntax::feature_gate;
 use syntax::parse::{self, token};
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::ast::AsmDialect;
 use syntax_pos::Span;
 use syntax::tokenstream;
@@ -39,7 +39,7 @@ fn next(&self) -> State {
     }
 }
 
-const OPTIONS: &[&str] = &["volatile", "alignstack", "intel"];
+const OPTIONS: &[Symbol] = &[sym::volatile, sym::alignstack, sym::intel];
 
 pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                        sp: Span,
@@ -47,7 +47,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                        -> Box<dyn base::MacResult + 'cx> {
     if !cx.ecfg.enable_asm() {
         feature_gate::emit_feature_err(&cx.parse_sess,
-                                       "asm",
+                                       sym::asm,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_ASM);
@@ -233,13 +233,13 @@ fn parse_inline_asm<'a>(
             Options => {
                 let (option, _) = p.parse_str()?;
 
-                if option == "volatile" {
+                if option == sym::volatile {
                     // Indicates that the inline assembly has side effects
                     // and must not be optimized out along with its outputs.
                     volatile = true;
-                } else if option == "alignstack" {
+                } else if option == sym::alignstack {
                     alignstack = true;
-                } else if option == "intel" {
+                } else if option == sym::intel {
                     dialect = AsmDialect::Intel;
                 } else {
                     cx.span_warn(p.prev_span, "unrecognized option");
index 8c9eb4bf2d8ffac3a6a98956d72e647a0e269814..77c53f402cc9f03b7f21bdea386aa457ac368d2d 100644 (file)
@@ -6,7 +6,7 @@
 use syntax::parse::token;
 use syntax::ptr::P;
 use syntax_pos::Span;
-use syntax_pos::symbol::Symbol;
+use syntax_pos::symbol::{Symbol, sym};
 use syntax::tokenstream::TokenTree;
 
 pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
@@ -15,7 +15,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
                               -> Box<dyn base::MacResult + 'cx> {
     if !cx.ecfg.enable_concat_idents() {
         feature_gate::emit_feature_err(&cx.parse_sess,
-                                       "concat_idents",
+                                       sym::concat_idents,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_CONCAT_IDENTS);
index b347092e1bc4c3208847acf79f3b6e93ee392f63..1b0d572324a7924dada216e2d413e2dfd9aedee6 100644 (file)
@@ -7,7 +7,7 @@
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
 use syntax_pos::Span;
 
 pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>,
@@ -37,7 +37,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>,
             match annitem.node {
                 ItemKind::Struct(_, Generics { ref params, .. }) |
                 ItemKind::Enum(_, Generics { ref params, .. }) => {
-                    if attr::contains_name(&annitem.attrs, "rustc_copy_clone_marker") &&
+                    if attr::contains_name(&annitem.attrs, sym::rustc_copy_clone_marker) &&
                         !params.iter().any(|param| match param.kind {
                             ast::GenericParamKind::Type { .. } => true,
                             _ => false,
index e5939e396e5c1372141a718c41e5387996f46247..a13dc07085f809403946684e4c03c129fa0858a6 100644 (file)
 use syntax::source_map::{self, respan};
 use syntax::util::map_in_place::MapInPlace;
 use syntax::ptr::P;
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
 use syntax::parse::ParseSess;
 use syntax_pos::{DUMMY_SP, Span};
 
@@ -426,7 +426,7 @@ pub fn expand_ext(self,
                     }
                 };
                 let is_always_copy =
-                    attr::contains_name(&item.attrs, "rustc_copy_clone_marker") &&
+                    attr::contains_name(&item.attrs, sym::rustc_copy_clone_marker) &&
                     has_no_type_params;
                 let use_temporaries = is_packed && is_always_copy;
 
@@ -464,8 +464,8 @@ pub fn expand_ext(self,
                 attrs.extend(item.attrs
                     .iter()
                     .filter(|a| {
-                        ["allow", "warn", "deny", "forbid", "stable", "unstable"]
-                            .contains(&a.name_or_empty().get())
+                        [sym::allow, sym::warn, sym::deny, sym::forbid, sym::stable, sym::unstable]
+                            .contains(&a.name_or_empty())
                     })
                     .cloned());
                 push(Annotatable::Item(P(ast::Item { attrs: attrs, ..(*newitem).clone() })))
index fff54814a38c40cd814197d03415c86e8c605661..c27de692d887cc050114ac6d7d4d3ec69410817c 100644 (file)
@@ -6,7 +6,7 @@
 use syntax::ext::build::AstBuilder;
 use syntax::ext::hygiene::{Mark, SyntaxContext};
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::Span;
 
 macro path_local($x:ident) {
@@ -139,7 +139,7 @@ fn call_intrinsic(cx: &ExtCtxt<'_>,
     let intrinsic_allowed_via_allow_internal_unstable = cx
         .current_expansion.mark.expn_info().unwrap()
         .allow_internal_unstable.map_or(false, |features| features.iter().any(|&s|
-            s == "core_intrinsics"
+            s == sym::core_intrinsics
         ));
     if intrinsic_allowed_via_allow_internal_unstable {
         span = span.with_ctxt(cx.backtrace());
index 24fbc9b6caf3fd8ddb4c9a14eb47d197bed2c852..9e54c0634b666b43a4bae4f333f27bc8fe774646 100644 (file)
@@ -12,7 +12,7 @@
 use syntax::feature_gate;
 use syntax::parse::token;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::tokenstream;
 use syntax_pos::{MultiSpan, Span, DUMMY_SP};
 
@@ -711,12 +711,12 @@ pub fn expand_format_args_nl<'cx>(
     //if !ecx.ecfg.enable_allow_internal_unstable() {
 
     // For some reason, the only one that actually works for `println` is the first check
-    if !sp.allows_unstable("format_args_nl") // the span is marked as `#[allow_insternal_unsable]`
+    if !sp.allows_unstable(sym::format_args_nl) // the span is marked `#[allow_insternal_unsable]`
         && !ecx.ecfg.enable_allow_internal_unstable()  // NOTE: when is this enabled?
         && !ecx.ecfg.enable_format_args_nl()  // enabled using `#[feature(format_args_nl]`
     {
         feature_gate::emit_feature_err(&ecx.parse_sess,
-                                       "format_args_nl",
+                                       sym::format_args_nl,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_FORMAT_ARGS_NL);
index 2baf530aedae7e37386ae7ae68104e64c8dfcf20..3f2853e4b0e20b3025d411eed2d8ddb8a2ea7ffc 100644 (file)
 use syntax::feature_gate;
 use syntax::parse::token;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::Span;
 use syntax::tokenstream;
 use smallvec::smallvec;
 
-pub const MACRO: &str = "global_asm";
+pub const MACRO: Symbol = sym::global_asm;
 
 pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                               sp: Span,
index 658ce98d268842bf4ccef0cf51a2e42457412d31..1be3990837cfe3cd6950e79307db6f1a7b6a3fa2 100644 (file)
@@ -2,6 +2,7 @@
 use syntax::feature_gate;
 use syntax::print;
 use syntax::tokenstream;
+use syntax::symbol::sym;
 use syntax_pos;
 
 pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt<'_>,
@@ -10,7 +11,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt<'_>,
                               -> Box<dyn base::MacResult + 'cx> {
     if !cx.ecfg.enable_log_syntax() {
         feature_gate::emit_feature_err(&cx.parse_sess,
-                                       "log_syntax",
+                                       sym::log_syntax,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_LOG_SYNTAX);
index f0390ba3d40cb0830a3fb2acc517f91a2fc0df4c..1eab739cf647064b292a83dc55de61bdbb1b61f4 100644 (file)
 use syntax::parse::ParseSess;
 use syntax::ptr::P;
 use syntax::symbol::Symbol;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax::visit::{self, Visitor};
 
 use syntax_pos::{Span, DUMMY_SP};
 
-const PROC_MACRO_KINDS: [&str; 3] = ["proc_macro_derive", "proc_macro_attribute", "proc_macro"];
+const PROC_MACRO_KINDS: [Symbol; 3] = [
+    sym::proc_macro_derive,
+    sym::proc_macro_attribute,
+    sym::proc_macro
+];
 
 struct ProcMacroDerive {
     trait_name: ast::Name,
@@ -139,7 +143,7 @@ fn collect_custom_derive(&mut self, item: &'a ast::Item, attr: &'a ast::Attribut
 
         let attributes_attr = list.get(1);
         let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {
-            if !attr.check_name("attributes") {
+            if !attr.check_name(sym::attributes) {
                 self.handler.span_err(attr.span(), "second argument must be `attributes`")
             }
             attr.meta_item_list().unwrap_or_else(|| {
@@ -231,7 +235,7 @@ fn collect_bang_proc_macro(&mut self, item: &'a ast::Item) {
 impl<'a> Visitor<'a> for CollectProcMacros<'a> {
     fn visit_item(&mut self, item: &'a ast::Item) {
         if let ast::ItemKind::MacroDef(..) = item.node {
-            if self.is_proc_macro_crate && attr::contains_name(&item.attrs, "macro_export") {
+            if self.is_proc_macro_crate && attr::contains_name(&item.attrs, sym::macro_export) {
                 let msg =
                     "cannot export macro_rules! macros from a `proc-macro` crate type currently";
                 self.handler.span_err(item.span, msg);
@@ -304,11 +308,11 @@ fn visit_item(&mut self, item: &'a ast::Item) {
             return;
         }
 
-        if attr.check_name("proc_macro_derive") {
+        if attr.check_name(sym::proc_macro_derive) {
             self.collect_custom_derive(item, attr);
-        } else if attr.check_name("proc_macro_attribute") {
+        } else if attr.check_name(sym::proc_macro_attribute) {
             self.collect_attr_proc_macro(item);
-        } else if attr.check_name("proc_macro") {
+        } else if attr.check_name(sym::proc_macro) {
             self.collect_bang_proc_macro(item);
         };
 
@@ -324,6 +328,7 @@ fn visit_mac(&mut self, mac: &'a ast::Mac) {
 
 // Creates a new module which looks like:
 //
+//      #[doc(hidden)]
 //      mod $gensym {
 //          extern crate proc_macro;
 //
@@ -357,6 +362,10 @@ fn mk_decls(
     });
     let span = DUMMY_SP.apply_mark(mark);
 
+    let hidden = cx.meta_list_item_word(span, Symbol::intern("hidden"));
+    let doc = cx.meta_list(span, Symbol::intern("doc"), vec![hidden]);
+    let doc_hidden = cx.attribute(span, doc);
+
     let proc_macro = Ident::from_str("proc_macro");
     let krate = cx.item(span,
                         proc_macro,
@@ -421,7 +430,7 @@ fn mk_decls(
         span,
         span,
         ast::Ident::with_empty_ctxt(Symbol::gensym("decls")),
-        vec![],
+        vec![doc_hidden],
         vec![krate, decls_static],
     ).map(|mut i| {
         i.vis = respan(span, ast::VisibilityKind::Public);
index 0fa5cd64360c065775168955f038af32e66f5d83..86ae6ab5fece5cbef9b2ae6be24e8dabed05799b 100644 (file)
@@ -7,7 +7,7 @@
 use syntax::attr;
 use syntax::ast;
 use syntax::print::pprust;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::{DUMMY_SP, Span};
 use syntax::source_map::{ExpnInfo, MacroAttribute};
 use std::iter;
@@ -206,15 +206,15 @@ enum ShouldPanic {
 }
 
 fn should_ignore(i: &ast::Item) -> bool {
-    attr::contains_name(&i.attrs, "ignore")
+    attr::contains_name(&i.attrs, sym::ignore)
 }
 
 fn should_fail(i: &ast::Item) -> bool {
-    attr::contains_name(&i.attrs, "allow_fail")
+    attr::contains_name(&i.attrs, sym::allow_fail)
 }
 
 fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
-    match attr::find_by_name(&i.attrs, "should_panic") {
+    match attr::find_by_name(&i.attrs, sym::should_panic) {
         Some(attr) => {
             let ref sd = cx.parse_sess.span_diagnostic;
 
@@ -222,7 +222,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
                 // Handle #[should_panic(expected = "foo")]
                 Some(list) => {
                     let msg = list.iter()
-                        .find(|mi| mi.check_name("expected"))
+                        .find(|mi| mi.check_name(sym::expected))
                         .and_then(|mi| mi.meta_item())
                         .and_then(|mi| mi.value_str());
                     if list.len() != 1 || msg.is_none() {
@@ -247,7 +247,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
 }
 
 fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
-    let has_should_panic_attr = attr::contains_name(&i.attrs, "should_panic");
+    let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic);
     let ref sd = cx.parse_sess.span_diagnostic;
     if let ast::ItemKind::Fn(ref decl, ref header, ref generics, _) = i.node {
         if header.unsafety == ast::Unsafety::Unsafe {
index 1ed1ab0a07b9683b4d25c7359ffe7aa57a5f737f..802037f6d22bbb16f7211268d6a91c9bca497213 100644 (file)
@@ -14,7 +14,7 @@
 use syntax::ext::hygiene::{self, Mark, SyntaxContext};
 use syntax::ast;
 use syntax::source_map::respan;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax_pos::{DUMMY_SP, Span};
 use syntax::source_map::{ExpnInfo, MacroAttribute};
 use syntax::feature_gate;
@@ -27,7 +27,7 @@ pub fn expand(
 ) -> Vec<Annotatable> {
     if !ecx.ecfg.enable_custom_test_frameworks() {
         feature_gate::emit_feature_err(&ecx.parse_sess,
-                                       "custom_test_frameworks",
+                                       sym::custom_test_frameworks,
                                        attr_sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_CUSTOM_TEST_FRAMEWORKS);
index 4d35daf3de998577d9c52499c74293d0b086dc43..eca658cb5473e2fb30d3a24ca5c43edda152d2e3 100644 (file)
@@ -1,6 +1,6 @@
 use syntax::ext::base::{self, ExtCtxt};
 use syntax::feature_gate;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
 use syntax_pos::Span;
 use syntax::tokenstream::TokenTree;
 
@@ -10,7 +10,7 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt<'_>,
                            -> Box<dyn base::MacResult + 'static> {
     if !cx.ecfg.enable_trace_macros() {
         feature_gate::emit_feature_err(&cx.parse_sess,
-                                       "trace_macros",
+                                       sym::trace_macros,
                                        sp,
                                        feature_gate::GateIssue::Language,
                                        feature_gate::EXPLAIN_TRACE_MACROS);
index a0b0052f26dab06e4251a72904f194db84d6effe..00cd00f2837849b10cbe646f4b7fcfc28796fada 100644 (file)
@@ -1,3 +1,4 @@
+use crate::symbol::{Symbol, sym};
 use std::fmt;
 use std::str::FromStr;
 
@@ -44,10 +45,10 @@ pub fn lint_name(&self) -> &'static str {
         }
     }
 
-    pub fn feature_name(&self) -> &'static str {
+    pub fn feature_name(&self) -> Symbol {
         match *self {
-            Edition::Edition2015 => "rust_2015_preview",
-            Edition::Edition2018 => "rust_2018_preview",
+            Edition::Edition2015 => sym::rust_2015_preview,
+            Edition::Edition2018 => sym::rust_2018_preview,
         }
     }
 
index 3f09405a5c8c6ed98850e25aab84920cf06b1fda..39859f25f97fb87b867d3abff651dc808c18d8c1 100644 (file)
@@ -33,7 +33,7 @@
 pub use span_encoding::{Span, DUMMY_SP};
 
 pub mod symbol;
-pub use symbol::symbols;
+pub use symbol::{Symbol, sym};
 
 mod analyze_source_file;
 
@@ -388,12 +388,12 @@ fn source_callee(info: ExpnInfo) -> ExpnInfo {
     /// Checks if a span is "internal" to a macro in which `#[unstable]`
     /// items can be used (that is, a macro marked with
     /// `#[allow_internal_unstable]`).
-    pub fn allows_unstable(&self, feature: &str) -> bool {
+    pub fn allows_unstable(&self, feature: Symbol) -> bool {
         match self.ctxt().outer().expn_info() {
             Some(info) => info
                 .allow_internal_unstable
                 .map_or(false, |features| features.iter().any(|&f|
-                    f == feature || f == "allow_internal_unstable_backcompat_hack"
+                    f == feature || f == sym::allow_internal_unstable_backcompat_hack
                 )),
             None => false,
         }
index c0c9c2a100042fd3d757b6d0bdf2090327add5d3..ec0ce4253fa2d397cef8f1b85795267f090d7e68 100644 (file)
         Union:              "union",
     }
 
-    // Other symbols that can be referred to with syntax_pos::symbols::*
-    Other {
+    // Symbols that can be referred to with syntax_pos::sym::*. The symbol is
+    // the stringified identifier unless otherwise specified (e.g.
+    // `proc_dash_macro` represents "proc-macro").
+    Symbols {
+        aarch64_target_feature,
+        abi,
+        abi_amdgpu_kernel,
+        abi_msp430_interrupt,
+        abi_ptx,
+        abi_sysv64,
+        abi_thiscall,
+        abi_unadjusted,
+        abi_vectorcall,
+        abi_x86_interrupt,
+        aborts,
+        advanced_slice_patterns,
+        adx_target_feature,
         alias,
         align,
+        alignstack,
+        all,
+        allocator,
+        allocator_internals,
         alloc_error_handler,
         allow,
+        allowed,
         allow_fail,
         allow_internal_unsafe,
         allow_internal_unstable,
+        allow_internal_unstable_backcompat_hack,
+        always,
+        any,
+        arbitrary_self_types,
+        arm_target_feature,
+        asm,
+        associated_consts,
+        associated_type_defaults,
+        associated_types,
+        async_await,
+        attr,
+        attributes,
+        attr_literals,
+        augmented_assignments,
         automatically_derived,
+        avx512_target_feature,
+        await_macro,
+        bin,
+        bind_by_move_pattern_guards,
+        block,
+        borrowck_graphviz_postflow,
+        borrowck_graphviz_preflow,
+        box_patterns,
+        box_syntax,
+        braced_empty_structs,
+        C,
+        cdylib,
         cfg,
         cfg_attr,
+        cfg_attr_multi,
+        cfg_target_feature,
+        cfg_target_has_atomic,
+        cfg_target_thread_local,
+        cfg_target_vendor,
+        clone,
+        clone_closures,
+        clone_from,
+        closure_to_fn_coercion,
+        cmpxchg16b_target_feature,
         cold,
+        compile_error,
         compiler_builtins,
+        concat_idents,
+        conservative_impl_trait,
+        console,
+        const_compare_raw_pointers,
+        const_fn,
+        const_fn_union,
+        const_generics,
+        const_indexing,
+        const_let,
+        const_panic,
+        const_raw_ptr_deref,
+        const_raw_ptr_to_usize_cast,
+        const_transmute,
+        contents,
+        convert,
+        copy_closures,
+        core,
+        core_intrinsics,
         crate_id,
+        crate_in_paths,
         crate_name,
         crate_type,
+        crate_visibility_modifier,
+        custom_attribute,
+        custom_derive,
+        custom_inner_attributes,
+        custom_test_frameworks,
+        c_variadic,
+        decl_macro,
         default_lib_allocator,
+        default_type_parameter_fallback,
+        default_type_params,
         deny,
         deprecated,
         derive,
         doc,
+        doc_alias,
+        doc_cfg,
+        doc_keyword,
+        doc_masked,
+        doc_spotlight,
+        document_private_items,
+        dotdoteq_in_patterns,
+        dotdot_in_tuple_patterns,
+        dropck_eyepatch,
+        dropck_parametricity,
+        drop_types_in_const,
+        dylib,
+        dyn_trait,
+        eh_personality,
+        eh_unwind_resume,
+        enable,
+        Err,
+        except,
+        exclusive_range_pattern,
+        exhaustive_integer_patterns,
+        exhaustive_patterns,
+        existential_type,
+        expected,
         export_name,
+        extern_absolute_paths,
+        external_doc,
+        extern_crate_item_prelude,
+        extern_crate_self,
+        extern_in_paths,
+        extern_prelude,
+        extern_types,
+        f16c_target_feature,
         feature,
         ffi_returns_twice,
+        field_init_shorthand,
+        file,
+        fn_must_use,
         forbid,
+        format_args_nl,
+        from,
+        From,
+        from_error,
+        from_generator,
+        from_ok,
         fundamental,
+        future,
+        Future,
+        generators,
+        generic_associated_types,
+        generic_param_attrs,
         global_allocator,
+        global_asm,
+        globs,
+        hexagon_target_feature,
+        hidden,
+        homogeneous_aggregate,
+        html_favicon_url,
+        html_logo_url,
+        html_no_source,
+        html_playground_url,
+        html_root_url,
+        i128,
+        i128_type,
+        i16,
+        i32,
+        i64,
+        i8,
+        ident,
+        if_let,
+        if_while_or_patterns,
         ignore,
+        impl_header_lifetime_elision,
+        impl_trait_in_bindings,
+        import_shadowing,
+        in_band_lifetimes,
         include,
+        inclusive_range_syntax,
+        infer_outlives_requirements,
+        infer_static_outlives_requirements,
         inline,
+        intel,
+        into_iter,
+        IntoIterator,
+        into_result,
+        intrinsics,
+        irrefutable_let_patterns,
+        isize,
+        issue,
+        issue_5723_bootstrap,
+        issue_tracker_base_url,
+        item_like_imports,
+        iter,
+        Iterator,
         keyword,
+        kind,
+        label,
+        label_break_value,
         lang,
+        lang_items,
+        lib,
         link,
+        linkage,
         link_args,
+        link_cfg,
+        link_llvm_intrinsics,
         link_name,
         link_section,
-        linkage,
+        lint_reasons,
+        local_inner_macros,
+        log_syntax,
+        loop_break_value,
+        macro_at_most_once_rep,
         macro_escape,
         macro_export,
+        macro_lifetime_matcher,
+        macro_literal_matcher,
+        macro_reexport,
+        macro_rules,
+        macros_in_extern,
         macro_use,
+        macro_vis_matcher,
         main,
+        managed_boxes,
         marker,
+        marker_trait_attr,
         masked,
+        match_beginning_vert,
+        match_default_bindings,
         may_dangle,
+        message,
+        min_const_fn,
+        min_const_unsafe_fn,
+        mips_target_feature,
+        mmx_target_feature,
+        module,
+        more_struct_aliases,
+        movbe_target_feature,
         must_use,
         naked,
+        naked_functions,
+        name,
         needs_allocator,
         needs_panic_runtime,
+        negate_unsigned,
+        never,
+        never_type,
+        next,
+        nll,
         no_builtins,
         no_core,
+        no_crate_inject,
         no_debug,
+        no_default_passes,
         no_implicit_prelude,
+        no_inline,
         no_link,
         no_main,
         no_mangle,
+        non_ascii_idents,
+        None,
+        non_exhaustive,
+        non_modrs_mods,
+        no_stack_check,
         no_start,
         no_std,
-        non_exhaustive,
+        not,
+        note,
+        Ok,
         omit_gdb_pretty_printer_section,
+        on,
+        on_unimplemented,
+        oom,
+        ops,
         optimize,
+        optimize_attribute,
+        optin_builtin_traits,
+        option,
+        Option,
+        opt_out_copy,
+        overlapping_marker_traits,
+        packed,
         panic_handler,
+        panic_impl,
+        panic_implementation,
         panic_runtime,
+        passes,
         path,
+        pattern_parentheses,
+        Pending,
+        pin,
+        Pin,
+        platform_intrinsics,
         plugin,
         plugin_registrar,
+        plugins,
+        Poll,
+        poll_with_tls_context,
+        powerpc_target_feature,
+        precise_pointer_size_matching,
+        prelude,
         prelude_import,
+        primitive,
+        proc_dash_macro: "proc-macro",
         proc_macro,
         proc_macro_attribute,
         proc_macro_derive,
+        proc_macro_expr,
+        proc_macro_gen,
+        proc_macro_hygiene,
+        proc_macro_mod,
+        proc_macro_non_items,
+        proc_macro_path_invoc,
         profiler_runtime,
+        pub_restricted,
+        pushpop_unsafe,
+        quad_precision_float,
+        question_mark,
+        quote,
+        Range,
+        RangeFrom,
+        RangeFull,
+        RangeInclusive,
+        RangeTo,
+        RangeToInclusive,
+        raw_identifiers,
+        Ready,
+        reason,
         recursion_limit,
         reexport_test_harness_main,
+        reflect,
+        relaxed_adts,
         repr,
+        repr128,
+        repr_align,
+        repr_align_enum,
+        repr_packed,
+        repr_simd,
+        repr_transparent,
+        re_rebalance_coherence,
+        result,
+        Result,
+        Return,
+        rlib,
+        rtm_target_feature,
+        rust,
+        rust_2015_preview,
+        rust_2018_preview,
+        rust_begin_unwind,
+        rustc_allocator_nounwind,
+        rustc_allow_const_fn_ptr,
         rustc_args_required_const,
+        rustc_attrs,
         rustc_clean,
         rustc_const_unstable,
         rustc_conversion_suggestion,
         rustc_copy_clone_marker,
         rustc_def_path,
         rustc_deprecated,
+        rustc_diagnostic_macros,
         rustc_dirty,
+        rustc_doc_only_macro,
+        rustc_dump_env_program_clauses,
         rustc_dump_program_clauses,
         rustc_dump_user_substs,
         rustc_error,
         rustc_layout_scalar_valid_range_end,
         rustc_layout_scalar_valid_range_start,
         rustc_mir,
+        rustc_object_lifetime_default,
         rustc_on_unimplemented,
         rustc_outlives,
         rustc_paren_sugar,
         rustc_partition_codegened,
         rustc_partition_reused,
+        rustc_peek,
+        rustc_peek_definite_init,
+        rustc_peek_maybe_init,
+        rustc_peek_maybe_uninit,
+        rustc_private,
         rustc_proc_macro_decls,
+        rustc_promotable,
         rustc_regions,
+        rustc_stable,
         rustc_std_internal_symbol,
         rustc_symbol_name,
         rustc_synthetic,
         rustc_then_this_would_need,
         rustc_transparent_macro,
         rustc_variance,
+        rustdoc,
+        rust_eh_personality,
+        rust_eh_unwind_resume,
+        rust_oom,
+        __rust_unstable_column,
+        rvalue_static_promotion,
         sanitizer_runtime,
+        self_in_typedefs,
+        self_struct_ctor,
+        Send,
         should_panic,
         simd,
+        simd_ffi,
+        since,
+        size,
+        slice_patterns,
+        slicing_syntax,
+        Some,
+        specialization,
+        speed,
         spotlight,
+        sse4a_target_feature,
         stable,
+        staged_api,
         start,
+        static_in_const,
+        staticlib,
+        static_nobundle,
+        static_recursion,
+        std,
+        stmt_expr_attributes,
+        stop_after_dataflow,
+        struct_field_attributes,
+        struct_inherit,
         structural_match,
+        struct_variant,
+        suggestion,
         target_feature,
+        target_has_atomic,
+        target_thread_local,
+        task,
+        tbm_target_feature,
+        termination_trait,
+        termination_trait_test,
+        test,
+        test_2018_feature,
+        test_accepted_feature,
+        test_removed_feature,
         test_runner,
         thread_local,
+        tool_attributes,
+        tool_lints,
+        trace_macros,
+        trait_alias,
+        transmute,
+        transparent,
+        trivial_bounds,
+        Try,
+        try_blocks,
+        tuple_indexing,
+        ty,
+        type_alias_enum_variants,
+        type_ascription,
         type_length_limit,
+        type_macros,
+        u128,
+        u16,
+        u32,
+        u64,
+        u8,
+        unboxed_closures,
+        underscore_const_names,
+        underscore_imports,
+        underscore_lifetimes,
+        uniform_paths,
+        universal_impl_trait,
+        unmarked_api,
+        unrestricted_attribute_tokens,
         unsafe_destructor_blind_to_params,
+        unsafe_no_drop_flag,
+        unsized_locals,
+        unsized_tuple_coercion,
         unstable,
+        untagged_unions,
         unwind,
+        unwind_attributes,
         used,
+        use_extern_macros,
+        use_nested_groups,
+        usize,
+        v1,
+        vis,
+        visible_private_types,
+        volatile,
         warn,
+        warn_directory_ownership,
+        wasm_import_module,
+        wasm_target_feature,
+        while_let,
+        windows,
         windows_subsystem,
+        Yield,
     }
 }
 
@@ -442,12 +822,6 @@ fn decode<D: Decoder>(d: &mut D) -> Result<Symbol, D::Error> {
     }
 }
 
-impl<T: std::ops::Deref<Target=str>> PartialEq<T> for Symbol {
-    fn eq(&self, other: &T) -> bool {
-        self.as_str() == other.deref()
-    }
-}
-
 // The `&'static str`s in this type actually point into the arena.
 //
 // Note that normal symbols are indexed upward from 0, and gensyms are indexed
@@ -557,7 +931,8 @@ pub fn name(self) -> Symbol {
     keywords!();
 }
 
-pub mod symbols {
+// This module has a very short name because it's used a lot.
+pub mod sym {
     use super::Symbol;
     symbols!();
 }
index 26612964c308fa8cd50d1cb4d25b4626ad02f5a1..c6afa90e4ee614d5c85d2961c8b1bff7424d955f 100644 (file)
@@ -1289,7 +1289,6 @@ fn num_cpus() -> usize {
     #[cfg(any(
         target_os = "freebsd",
         target_os = "dragonfly",
-        target_os = "bitrig",
         target_os = "netbsd"
     ))]
     fn num_cpus() -> usize {
index f3fda9eaa75f4bddddf4d162a7f20f6e5b325af1..70f591e653baf4ae139625a2ca253f77e221bc59 100644 (file)
@@ -26,8 +26,6 @@ fn main() {
         println!("cargo:rustc-link-lib=c++abi");
     } else if target.contains("solaris") {
         println!("cargo:rustc-link-lib=gcc_s");
-    } else if target.contains("bitrig") {
-        println!("cargo:rustc-link-lib=c++abi");
     } else if target.contains("dragonfly") {
         println!("cargo:rustc-link-lib=gcc_pic");
     } else if target.contains("windows-gnu") {
index 84abffda0e03b03c62bdfc3cfeda1c2cf1f88c85..eb38a1888d1d29b2d2c6b31428a5201cd8fba0ff 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 84abffda0e03b03c62bdfc3cfeda1c2cf1f88c85
+Subproject commit eb38a1888d1d29b2d2c6b31428a5201cd8fba0ff
index 40bbd2821eff91dc10330f39f90a9bc98cff6649..52543297ead647f1f6874204e3e0ec70b3b66b9f 100644 (file)
@@ -1,6 +1,5 @@
 // This test is for *-windows-msvc only.
 // ignore-android
-// ignore-bitrig
 // ignore-cloudabi
 // ignore-dragonfly
 // ignore-emscripten
index eb826590523b73cd2bf14b1842cc8ba5ba56c885..1cebc49236feedf66de871e825385ee66413d068 100644 (file)
@@ -19,7 +19,7 @@ pub struct Bool {
     b: bool,
 }
 
-// CHECK: target triple = "i686-apple-darwin"
+// CHECK: target triple = "i686-apple-macosx10.7.0"
 #[no_mangle]
 pub extern "C" fn structbool() -> Bool {
     Bool { b: true }
index bbe0d81de3d421b93a94e96d6edefd7cf4070736..f2fd297dc70f77d37e24d61217575f35f9980b39 100644 (file)
@@ -1,6 +1,5 @@
 // This test is for *-windows-msvc only.
 // ignore-android
-// ignore-bitrig
 // ignore-cloudabi
 // ignore-dragonfly
 // ignore-emscripten
index 58a11d1095bbe0a79b72471427c15c0f798c9e4e..c5ac73b54e186c065fc32343ccd3d41925e42875 100644 (file)
@@ -19,7 +19,7 @@ pub struct Bool {
     b: bool,
 }
 
-// CHECK: target triple = "x86_64-apple-darwin"
+// CHECK: target triple = "x86_64-apple-macosx10.7.0"
 #[no_mangle]
 pub extern "C" fn structbool() -> Bool {
     Bool { b: true }
index bd94db09520288c593995cd866c8f043435f6223..0c0e331da1d5aaa47c3365486c46e05377c0487c 100644 (file)
@@ -6,10 +6,6 @@
 # is compiled with LTO, it shouldn't strip the symbol from `foo`, and that's the
 # only way that `foo.c` will successfully compile.
 
-ifeq ($(UNAME),Bitrig)
-       EXTRACFLAGS := -lc $(EXTRACFLAGS) $(EXTRACXXFLAGS)
-endif
-
 all:
        $(RUSTC) foo.rs --crate-type=rlib
        $(RUSTC) bar.rs --crate-type=staticlib -C lto -L. -o $(TMPDIR)/libbar.a
index 4b9ab0b7c23d74e9f94c95581dafd429e03e6c40..3b4df73cdfd6dbcf8f0d59f5cff9b48e51d5aa5d 100644 (file)
@@ -88,10 +88,6 @@ else
 ifeq ($(UNAME),FreeBSD)
        EXTRACFLAGS := -lm -lpthread -lgcc_s
 else
-ifeq ($(UNAME),Bitrig)
-       EXTRACFLAGS := -lm -lpthread
-       EXTRACXXFLAGS := -lc++ -lc++abi
-else
 ifeq ($(UNAME),SunOS)
        EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv
 else
@@ -106,7 +102,6 @@ endif
 endif
 endif
 endif
-endif
 
 REMOVE_DYLIBS     = rm $(TMPDIR)/$(call DYLIB_GLOB,$(1))
 REMOVE_RLIBS      = rm $(TMPDIR)/$(call RLIB_GLOB,$(1))
index 3976da3113190f7fba9e13818455585b2a59da00..838b1a2719b9f5551bbd2970f60bf57e71a4a662 100644 (file)
@@ -2,7 +2,6 @@
 
 # ignore-freebsd
 # ignore-openbsd
-# ignore-bitrig
 # ignore-sunos
 
 HOST := $(shell $(RUSTC) -vV | grep 'host:' | sed 's/host: //')
index 699972c9a85bd458ca0153d4c78fd3e8bc97b3c0..c6b33fbc75ee23dbd29e30c3a5c2ff325eea6a95 100644 (file)
@@ -14,7 +14,7 @@
 use syntax::attr;
 use syntax::ext::base::{MultiDecorator, ExtCtxt, Annotatable};
 use syntax::ext::build::AstBuilder;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
 use syntax::ptr::P;
 use syntax_ext::deriving::generic::{TraitDef, MethodDef, combine_substructure};
 use syntax_ext::deriving::generic::{Substructure, Struct, EnumMatching};
@@ -71,7 +71,7 @@ fn totalsum_substructure(cx: &mut ExtCtxt, trait_span: Span,
     };
 
     fields.iter().fold(cx.expr_isize(trait_span, 0), |acc, ref item| {
-        if attr::contains_name(&item.attrs, "ignore") {
+        if attr::contains_name(&item.attrs, sym::ignore) {
             acc
         } else {
             cx.expr_binary(item.span, ast::BinOpKind::Add, acc,
index 76d0906f97c9a85e9179ff5e0b493b7dfc4104d5..40e0115c623eeca63f4858335bc8d0874b5f636e 100644 (file)
@@ -23,7 +23,7 @@
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
     reg.register_late_lint_pass(box MissingWhitelistedAttrPass);
-    reg.register_attribute("whitelisted_attr".to_string(), Whitelisted);
+    reg.register_attribute(Symbol::intern("whitelisted_attr"), Whitelisted);
 }
 
 declare_lint! {
@@ -48,7 +48,7 @@ fn check_fn(&mut self,
             _ => cx.tcx.hir().expect_item_by_hir_id(cx.tcx.hir().get_parent_item(id)),
         };
 
-        if !attr::contains_name(&item.attrs, "whitelisted_attr") {
+        if !attr::contains_name(&item.attrs, Symbol::intern("whitelisted_attr")) {
             cx.span_lint(MISSING_WHITELISTED_ATTR, span,
                          "Missing 'whitelisted_attr' attribute");
         }
index f34e10218d455f3222df9e95828711c094c1f211..8c7bd7222e73cb5294594c32fa854d10f4b8c863 100644 (file)
@@ -11,6 +11,7 @@
 use rustc_plugin::Registry;
 use rustc::hir;
 use syntax::attr;
+use syntax::symbol::Symbol;
 
 macro_rules! fake_lint_pass {
     ($struct:ident, $lints:expr, $($attr:expr),*) => {
@@ -49,19 +50,19 @@ fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) {
 fake_lint_pass! {
     PassOkay,
     lint_array!(CRATE_NOT_OKAY), // Single lint
-    "rustc_crate_okay"
+    Symbol::intern("rustc_crate_okay")
 }
 
 fake_lint_pass! {
     PassRedBlue,
     lint_array!(CRATE_NOT_RED, CRATE_NOT_BLUE), // Multiple lints
-    "rustc_crate_red", "rustc_crate_blue"
+    Symbol::intern("rustc_crate_red"), Symbol::intern("rustc_crate_blue")
 }
 
 fake_lint_pass! {
     PassGreyGreen,
     lint_array!(CRATE_NOT_GREY, CRATE_NOT_GREEN, ), // Trailing comma
-    "rustc_crate_grey", "rustc_crate_green"
+    Symbol::intern("rustc_crate_grey"), Symbol::intern("rustc_crate_green")
 }
 
 #[plugin_registrar]
index 7f038ddecc1fab1a676eeebe2d7313059bcc6a02..279a30d6c2eebcb7645f8820129016de73ef346b 100644 (file)
@@ -32,7 +32,6 @@ macro_rules! dump_and_die {
                     all(target_os = "linux", target_arch = "arm"),
                     target_os = "freebsd",
                     target_os = "dragonfly",
-                    target_os = "bitrig",
                     target_os = "openbsd")) {
             // skip these platforms as this support isn't implemented yet.
         } else {
index 91624e92fbe753ad0801e589095e72f008ab8465..c5b9d837b47a896085dc83fc23e38137388394cd 100644 (file)
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(const_ptr_nonnull)]
-
 use std::ptr::NonNull;
 
 const DANGLING: NonNull<u32> = NonNull::dangling();
index cb6a82a15da1f710b25aee825eaee637ac96682e..8b7025b7be7daea4368317a84a43181e4506de2e 100644 (file)
@@ -18,9 +18,6 @@ mod hello;
 #[cfg(target_os = "dragonfly")]
 mod hello;
 
-#[cfg(target_os = "bitrig")]
-mod hello;
-
 #[cfg(target_os = "android")]
 mod hello;
 
index 921fbaf4942caed917fdcb86fec12bb23603f505..79759daba501cfdeef1f9816075554c527e0cd42 100644 (file)
@@ -6,7 +6,6 @@
 // Tests parallel codegen - this can fail if the symbol for the anonymous
 // closure in `sum` pollutes the second codegen unit from the first.
 
-// ignore-bitrig
 // compile-flags: -C codegen_units=2
 
 #![feature(iter_arith)]
index 9a1f53b48933af6483ddcfcd77d3d796abafa98b..1e3a641b7cf94cf621ae362aca26ed2d3d8a4383 100644 (file)
@@ -1,4 +1,5 @@
 #![feature(impl_trait_in_bindings)]
+//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
 
 use std::fmt::Debug;
 
diff --git a/src/test/run-pass/impl-trait-in-bindings.stderr b/src/test/run-pass/impl-trait-in-bindings.stderr
new file mode 100644 (file)
index 0000000..4896deb
--- /dev/null
@@ -0,0 +1,6 @@
+warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
+  --> $DIR/impl-trait-in-bindings.rs:1:12
+   |
+LL | #![feature(impl_trait_in_bindings)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^
+
index 5a21e1dd81759f090664cfa024eed77c704c5c31..9a9843375e4c529b213da54454c1e90fc1e0a13e 100644 (file)
@@ -1,6 +1,7 @@
 // run-pass
 
 #![allow(warnings)]
+#![feature(generators)]
 
 use std::fmt::Debug;
 
@@ -112,6 +113,11 @@ impl<'unnecessary_lifetime> MyVec {
     fn iter_doesnt_capture_unnecessary_lifetime<'s>(&'s self) -> impl Iterator<Item = &'s u8> {
         self.0.iter().flat_map(|inner_vec| inner_vec.iter())
     }
+
+    fn generator_doesnt_capture_unnecessary_lifetime<'s: 's>() -> impl Sized {
+        || yield
+    }
 }
 
+
 fn main() {}
index 19e5671062054bcd2d41a43dc41c93ad31c05a16..ac9fb94c37507c6f82a9b181eba6276e1232fda2 100644 (file)
@@ -40,18 +40,6 @@ pub fn main() {
     }
 }
 
-#[cfg(target_os = "bitrig")]
-mod m {
-    #[main]
-    #[cfg(target_arch = "x86_64")]
-    pub fn main() {
-        unsafe {
-            assert_eq!(::rusti::pref_align_of::<u64>(), 8);
-            assert_eq!(::rusti::min_align_of::<u64>(), 8);
-        }
-    }
-}
-
 #[cfg(target_os = "windows")]
 mod m {
     #[main]
index f5c633d250b9ecfbcc3287c0b5433e1427e7a615..02bbab30e9c6e55a97e01ecb09b9b1da185c3e2e 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-// ignore-bitrig
 // compile-flags: -C codegen-units=3
 // aux-build:sepcomp_cci_lib.rs
 
index 18af785c1bea1002b3a226e5a8d99b816d92c59e..c4ccf23c47ab44f386714be3c68315a11abeae82 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-// ignore-bitrig
 // compile-flags: -C codegen-units=3
 // aux-build:sepcomp-extern-lib.rs
 
index 96bcc260bdf5c229adefe1009ba2a37d8cc8cb61..f56769e2b8c6d2baebd36559c88590831d42bffa 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(dead_code)]
-// ignore-bitrig
 // compile-flags: -C codegen-units=3
 
 // Test references to items that haven't been codegened yet.
index c4ea17225b44ebad919cafc476d77665a0bef283..a432c89606e339dab939666f1de5f1280660f318 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-// ignore-bitrig
 // compile-flags: -C codegen-units=3
 
 // Test basic separate compilation functionality.  The functions should be able
index e0c6b268b177c96ec1b3bf4637312925e6b8f5ca..5457c8a0ae97d29be2b715cb57f4128d5d9e0478 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(dead_code)]
-// ignore-bitrig
 // compile-flags: -C codegen-units=3
 
 // Test references to static items across compilation units.
index 01dbea08098bd7680e1c71cde732a4d7cb4438aa..50a4e043943f0d0d9c1c9c55ed68aa0c078e55d7 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(dead_code)]
-// ignore-bitrig
 // compile-flags: -C codegen-units=3
 // ignore-emscripten no threads support
 
index d211eed131e5dcef92df2250604fe94dcd99ffcb..07e60114018929b6694724f30891b994c7ec7b77 100644 (file)
@@ -55,15 +55,6 @@ pub fn size() -> usize { 16 }
     }
 }
 
-#[cfg(target_os = "bitrig")]
-mod m {
-    #[cfg(target_arch = "x86_64")]
-    pub mod m {
-        pub fn align() -> usize { 8 }
-        pub fn size() -> usize { 16 }
-    }
-}
-
 #[cfg(target_os = "windows")]
 mod m {
     #[cfg(target_arch = "x86")]
index c90f9024af1419db0ce2f7e7b204ad5827bad57c..d4476ab0a310f02862b45737c7b5fe77b7d73420 100644 (file)
@@ -1,5 +1,4 @@
 // ignore-android needs extra network permissions
-// ignore-bitrig system ulimit (Too many open files)
 // ignore-cloudabi no global network namespace access
 // ignore-emscripten no threads or sockets support
 // ignore-netbsd system ulimit (Too many open files)
index 11a45a58895d95b83c599174875fc77f3b38e840..1b6ffc4c2bfdac4fc16bb37596f5a0a3661d2647 100644 (file)
@@ -23,7 +23,6 @@ pub fn main() {
 }
 
 #[cfg(any(target_os = "android",
-          target_os = "bitrig",
           target_os = "cloudabi",
           target_os = "dragonfly",
           target_os = "emscripten",
index c83e7bdb9983e25fc4865903b0947b6370980f66..039124f31ff4233bb59dfdc01652ff3f4eaae38b 100644 (file)
@@ -8,14 +8,14 @@
 extern crate rustc;
 extern crate rustc_plugin;
 
+use syntax::symbol::Symbol;
 use syntax::feature_gate::AttributeType;
 use rustc_plugin::Registry;
 
 
-
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
-    reg.register_attribute("foo".to_owned(), AttributeType::Normal);
-    reg.register_attribute("bar".to_owned(), AttributeType::CrateLevel);
-    reg.register_attribute("baz".to_owned(), AttributeType::Whitelisted);
+    reg.register_attribute(Symbol::intern("foo"), AttributeType::Normal);
+    reg.register_attribute(Symbol::intern("bar"), AttributeType::CrateLevel);
+    reg.register_attribute(Symbol::intern("baz"), AttributeType::Whitelisted);
 }
index e8f1d2eedf559cc44979d2e4f8ab356b6d2b4fe3..7656b15721adafb03db8ff576d84d1b5c1c745dc 100644 (file)
@@ -11,6 +11,7 @@
 use rustc_plugin::Registry;
 use rustc::hir;
 use syntax::attr;
+use syntax::symbol::Symbol;
 
 declare_lint! {
     CRATE_NOT_OKAY,
@@ -22,7 +23,7 @@
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
     fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) {
-        if !attr::contains_name(&krate.attrs, "crate_okay") {
+        if !attr::contains_name(&krate.attrs, Symbol::intern("crate_okay")) {
             cx.span_lint(CRATE_NOT_OKAY, krate.span,
                          "crate is not marked with #![crate_okay]");
         }
index 1d204e7bfcffabaf87f413df39960095b286f096..0deb1bf091508d01c951f4d61891e7cc2c6f4a3b 100644 (file)
@@ -20,7 +20,7 @@
 
 impl EarlyLintPass for Pass {
     fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
-        if it.ident.name == "lintme" {
+        if it.ident.name.as_str() == "lintme" {
             cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
         }
     }
index 182d2899da1853ee4d51c4e2e1ca7cb85d876399..64664377cd9435c05b6e07336d0c60c64f26e998 100644 (file)
 
 impl EarlyLintPass for Pass {
     fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
-        if it.ident.name == "lintme" {
+        if it.ident.name.as_str() == "lintme" {
             cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
         }
-        if it.ident.name == "lintmetoo" {
+        if it.ident.name.as_str() == "lintmetoo" {
             cx.span_lint(TEST_GROUP, it.span, "item is named 'lintmetoo'");
         }
     }
index aae25b2721e4d9497375b270129a884a94a0bf48..571779dfa1ae72f740d58e14cdc87170ff622aa1 100644 (file)
@@ -1,8 +1,8 @@
 error: unexpected token: `!`
-  --> $DIR/attr-eq-token-tree.rs:3:11
+  --> $DIR/attr-eq-token-tree.rs:3:13
    |
 LL | #[my_attr = !]
-   |           ^
+   |             ^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs
new file mode 100644 (file)
index 0000000..c3f5e36
--- /dev/null
@@ -0,0 +1,11 @@
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+// We should probably be able to infer the types here. However, this test is checking that we don't
+// get an ICE in this case. It may be modified later to not be an error.
+
+struct Foo<const NUM_BYTES: usize>(pub [u8; NUM_BYTES]);
+
+fn main() {
+    let _ = Foo::<3>([1, 2, 3]); //~ ERROR type annotations needed
+}
diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr
new file mode 100644 (file)
index 0000000..a0641bd
--- /dev/null
@@ -0,0 +1,15 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/cannot-infer-type-for-const-param.rs:1:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+
+error[E0282]: type annotations needed
+  --> $DIR/cannot-infer-type-for-const-param.rs:10:19
+   |
+LL |     let _ = Foo::<3>([1, 2, 3]);
+   |                   ^ cannot infer type for `{integer}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/const-generics/invalid-const-arg-for-type-param.rs b/src/test/ui/const-generics/invalid-const-arg-for-type-param.rs
new file mode 100644 (file)
index 0000000..b069cd8
--- /dev/null
@@ -0,0 +1,9 @@
+use std::convert::TryInto;
+
+struct S;
+
+fn main() {
+    let _: u32 = 5i32.try_into::<32>().unwrap(); //~ ERROR wrong number of const arguments
+    S.f::<0>(); //~ ERROR no method named `f`
+    S::<0>; //~ ERROR  wrong number of const arguments
+}
diff --git a/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr b/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr
new file mode 100644 (file)
index 0000000..8f3f916
--- /dev/null
@@ -0,0 +1,25 @@
+error[E0107]: wrong number of const arguments: expected 0, found 1
+  --> $DIR/invalid-const-arg-for-type-param.rs:6:34
+   |
+LL |     let _: u32 = 5i32.try_into::<32>().unwrap();
+   |                                  ^^ unexpected const argument
+
+error[E0599]: no method named `f` found for type `S` in the current scope
+  --> $DIR/invalid-const-arg-for-type-param.rs:7:7
+   |
+LL | struct S;
+   | --------- method `f` not found for this
+...
+LL |     S.f::<0>();
+   |       ^
+
+error[E0107]: wrong number of const arguments: expected 0, found 1
+  --> $DIR/invalid-const-arg-for-type-param.rs:8:9
+   |
+LL |     S::<0>;
+   |         ^ unexpected const argument
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0107, E0599.
+For more information about an error, try `rustc --explain E0107`.
index 03867a8e43b1058ce2eacc11ef27e29e856f790b..359725a41c105892aedde9f8ecdcbc8460050c59 100644 (file)
@@ -1,8 +1,8 @@
 error: unexpected token: `,`
-  --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:15
+  --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:17
    |
 LL |         [_, 99.., _] => {},
-   |               ^^
+   |                 ^
 
 error: aborting due to previous error
 
index 5ac435bf011e495216ebada90e00e3a8cb94d79f..8f849d7b3f87c5a53f8af1f5d302b970afe481f0 100644 (file)
@@ -1,8 +1,8 @@
 error: unexpected token: `]`
-  --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:15
+  --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:17
    |
 LL |         [_, 99..] => {},
-   |               ^^
+   |                 ^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/existential_types/issue-60655-latebound-regions.rs b/src/test/ui/existential_types/issue-60655-latebound-regions.rs
new file mode 100644 (file)
index 0000000..a4fe865
--- /dev/null
@@ -0,0 +1,30 @@
+// Test that existential types are allowed to contain late-bound regions.
+
+// compile-pass
+// edition:2018
+
+#![feature(async_await, existential_type)]
+
+use std::future::Future;
+
+pub existential type Func: Sized;
+
+// Late bound region should be allowed to escape the function, since it's bound
+// in the type.
+fn null_function_ptr() -> Func {
+    None::<for<'a> fn(&'a ())>
+}
+
+async fn async_nop(_: &u8) {}
+
+pub existential type ServeFut: Future<Output=()>;
+
+// Late bound regions occur in the generator witness type here.
+fn serve() -> ServeFut {
+    async move {
+        let x = 5;
+        async_nop(&x).await
+    }
+}
+
+fn main() {}
index 5f623321943a32464ff41207fd5d86f51540bcd3..d4eef29ed32074cc5a2a8f8db7c48aa71de8af95 100644 (file)
@@ -1,4 +1,5 @@
 #![feature(impl_trait_in_bindings)]
+//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
 
 const FOO: impl Copy = 42;
 
index 8b2514c050142d74f4adbbe9e0c4dbb22eea8af9..d0a6a4ee578f71fd0db0d8cfc8bb8643a503cd60 100644 (file)
@@ -1,17 +1,23 @@
+warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
+  --> $DIR/bindings-opaque.rs:1:12
+   |
+LL | #![feature(impl_trait_in_bindings)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope
-  --> $DIR/bindings-opaque.rs:10:17
+  --> $DIR/bindings-opaque.rs:11:17
    |
 LL |     let _ = FOO.count_ones();
    |                 ^^^^^^^^^^
 
 error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope
-  --> $DIR/bindings-opaque.rs:12:17
+  --> $DIR/bindings-opaque.rs:13:17
    |
 LL |     let _ = BAR.count_ones();
    |                 ^^^^^^^^^^
 
 error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope
-  --> $DIR/bindings-opaque.rs:14:17
+  --> $DIR/bindings-opaque.rs:15:17
    |
 LL |     let _ = foo.count_ones();
    |                 ^^^^^^^^^^
index 91d092634a90100ca3b2bf1cead2bab73634e751..104a44d65662e94b40f06e8b877fa26f7e531189 100644 (file)
@@ -1,4 +1,5 @@
 #![feature(impl_trait_in_bindings)]
+//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
 
 fn a<T: Clone>(x: T) {
     const foo: impl Clone = x;
index a5bf583afeaf6a75e09a894cb9d999dc65b6185b..c66836ab8e5af09ab003a8d8091c0dadc43a608c 100644 (file)
@@ -1,23 +1,29 @@
+warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
+  --> $DIR/bindings.rs:1:12
+   |
+LL | #![feature(impl_trait_in_bindings)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/bindings.rs:4:29
+  --> $DIR/bindings.rs:5:29
    |
 LL |     const foo: impl Clone = x;
    |                             ^ non-constant value
 
 error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/bindings.rs:10:33
+  --> $DIR/bindings.rs:11:33
    |
 LL |         const foo: impl Clone = x;
    |                                 ^ non-constant value
 
 error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/bindings.rs:17:33
+  --> $DIR/bindings.rs:18:33
    |
 LL |         const foo: impl Clone = x;
    |                                 ^ non-constant value
 
 error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/bindings.rs:24:33
+  --> $DIR/bindings.rs:25:33
    |
 LL |         const foo: impl Clone = x;
    |                                 ^ non-constant value
index a982b176ecda1c280353c5246c7b4005b1b0bffb..90a7519074b53bebbda8c04bc9f7d3197aa34af6 100644 (file)
@@ -16,4 +16,8 @@ fn make_identity() -> impl Sized {
     |x: &'static i32| x
 }
 
+fn make_identity_static() -> impl Sized + 'static {
+    |x: &'static i32| x
+}
+
 fn main() {}
index 29e271c68ec9068562d430508509870a3728d8c6..11f1a392239dcdeb491afbe0b5615ad47e49398e 100644 (file)
@@ -17,6 +17,13 @@ fn wrapped_closure() -> impl Sized {
     A(f)
 }
 
+fn wrapped_closure_with_bound() -> impl Sized + 'static {
+    let f = |x| x;
+    f(&0);
+    A(f)
+}
+
 fn main() {
     let x: Box<dyn Send> = Box::new(wrapped_closure());
+    let y: Box<dyn Send> = Box::new(wrapped_closure_with_bound());
 }
diff --git a/src/test/ui/issues/issue-60662.rs b/src/test/ui/issues/issue-60662.rs
new file mode 100644 (file)
index 0000000..fe4eaff
--- /dev/null
@@ -0,0 +1,11 @@
+// compile-pass
+// compile-flags: -Z unpretty=hir
+
+#![feature(existential_type)]
+
+trait Animal {
+}
+
+fn main() {
+    pub existential type ServeFut: Animal;
+}
diff --git a/src/test/ui/issues/issue-60662.stdout b/src/test/ui/issues/issue-60662.stdout
new file mode 100644 (file)
index 0000000..5acfdf9
--- /dev/null
@@ -0,0 +1,14 @@
+// compile-pass
+// compile-flags: -Z unpretty=hir
+
+#![feature(existential_type)]
+#[prelude_import]
+use ::std::prelude::v1::*;
+#[macro_use]
+extern crate std;
+
+trait Animal { }
+
+fn main() {
+              pub existential type ServeFut : Animal;
+          }
index aa1cd94b0c6382c276731ed927ee503c3294785f..d28ce25341d3ac89509674565b09e7635aae21e9 100644 (file)
@@ -1,8 +1,8 @@
 error: unexpected token: `$`
-  --> $DIR/macro-attribute.rs:1:7
+  --> $DIR/macro-attribute.rs:1:9
    |
 LL | #[doc = $not_there]
-   |       ^
+   |         ^
 
 error: aborting due to previous error
 
index e452435968baca28a15b1c4ec1e705da02c8a4cc..7c4ca3c017e7b33ad8634147566bf4c234fe64b6 100644 (file)
@@ -2,8 +2,7 @@
 
 macro_rules! check {
     ($expr: expr) => (
-        #[my_attr = $expr] //~ ERROR suffixed literals are not allowed in attributes
-                           //~| ERROR unexpected token: `-0`
+        #[my_attr = $expr] //~ ERROR unexpected token: `-0`
                            //~| ERROR unexpected token: `0 + 0`
         use main as _;
     );
@@ -11,7 +10,7 @@ macro_rules! check {
 
 check!("0"); // OK
 check!(0); // OK
-check!(0u8); // ERROR, see above
+check!(0u8); //~ ERROR suffixed literals are not allowed in attributes
 check!(-0); // ERROR, see above
 check!(0 + 0); // ERROR, see above
 
index efeede0148dac70e7ef6d1376dad53a8066b9e83..e805416172bab8d58133ea77e026cf0546341cc8 100644 (file)
@@ -1,28 +1,25 @@
 error: suffixed literals are not allowed in attributes
-  --> $DIR/malformed-interpolated.rs:5:21
+  --> $DIR/malformed-interpolated.rs:13:8
    |
-LL |         #[my_attr = $expr]
-   |                     ^^^^^
-...
-LL | check!(0u8); // ERROR, see above
-   | ------------ in this macro invocation
+LL | check!(0u8);
+   |        ^^^
    |
    = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.).
 
 error: unexpected token: `-0`
-  --> $DIR/malformed-interpolated.rs:5:19
+  --> $DIR/malformed-interpolated.rs:5:21
    |
 LL |         #[my_attr = $expr]
-   |                   ^
+   |                     ^^^^^
 ...
 LL | check!(-0); // ERROR, see above
    | ----------- in this macro invocation
 
 error: unexpected token: `0 + 0`
-  --> $DIR/malformed-interpolated.rs:5:19
+  --> $DIR/malformed-interpolated.rs:5:21
    |
 LL |         #[my_attr = $expr]
-   |                   ^
+   |                     ^^^^^
 ...
 LL | check!(0 + 0); // ERROR, see above
    | -------------- in this macro invocation
index 8a016bf87795b8b9239833ccb2b97f669de6d196..a8f7299f89937a29898d7fd31052cec7de32bf22 100644 (file)
@@ -25,7 +25,7 @@ fn next(&mut self) -> Option<Self::Item> {
 fn bug<'a>() -> impl Iterator<Item = &'a str> {
     GenIter(move || {
         let mut s = String::new();
-        yield &s[..] //~ ERROR `s` does not live long enough [E0597]
+        yield &s[..] //~ ERROR cannot yield value referencing local variable `s` [E0515]
         //~| ERROR borrow may still be in use when generator yields
     })
 }
index 66c2995efc8805e12c29a13a913bd1f63b33e38d..86a8cdc42ff9fdf1e344ae54ae628241c1a135c8 100644 (file)
@@ -1,11 +1,11 @@
-error[E0597]: `s` does not live long enough
-  --> $DIR/issue-55850.rs:28:16
+error[E0515]: cannot yield value referencing local variable `s`
+  --> $DIR/issue-55850.rs:28:9
    |
 LL |         yield &s[..]
-   |                ^ borrowed value does not live long enough
-LL |
-LL |     })
-   |     - `s` dropped here while still borrowed
+   |         ^^^^^^^-^^^^
+   |         |      |
+   |         |      `s` is borrowed here
+   |         yields a value referencing data owned by the current function
 
 error[E0626]: borrow may still be in use when generator yields
   --> $DIR/issue-55850.rs:28:16
@@ -15,5 +15,5 @@ LL |         yield &s[..]
 
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0597, E0626.
-For more information about an error, try `rustc --explain E0597`.
+Some errors have detailed explanations: E0515, E0626.
+For more information about an error, try `rustc --explain E0515`.
index ffbfc583e8a7575ca240c68dd00832e3b6cf3a1f..2d772dae69125c74ffc2bf4358471a11cf086ca1 100644 (file)
@@ -1,8 +1,8 @@
 error: unexpected token: `]`
-  --> $DIR/attr-bad-meta-2.rs:1:8
+  --> $DIR/attr-bad-meta-2.rs:1:9
    |
 LL | #[path =]
-   |        ^
+   |         ^
 
 error: aborting due to previous error
 
index 61ae40b355d38b178aeb2e15bf7892e6003f8738..f9832214c6800b4c7ba8fc0012d47ecc78a86b22 100644 (file)
@@ -1,8 +1,8 @@
 error: unexpected token: `)`
-  --> $DIR/pat-tuple-5.rs:3:14
+  --> $DIR/pat-tuple-5.rs:3:16
    |
 LL |         (pat ..) => {}
-   |              ^^
+   |                ^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/proc-macro/no-missing-docs.rs b/src/test/ui/proc-macro/no-missing-docs.rs
new file mode 100644 (file)
index 0000000..e5a5f8b
--- /dev/null
@@ -0,0 +1,16 @@
+//! Verify that the `decls` module implicitly added by the compiler does not cause `missing_docs`
+//! warnings.
+
+// compile-pass
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+#![deny(missing_docs)]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+/// Foo1.
+#[proc_macro]
+pub fn foo1(input: TokenStream) -> TokenStream { input }
diff --git a/src/test/ui/save-analysis/issue-59134-0.rs b/src/test/ui/save-analysis/issue-59134-0.rs
new file mode 100644 (file)
index 0000000..3158328
--- /dev/null
@@ -0,0 +1,12 @@
+// compile-flags: -Zsave-analysis
+
+// Check that this doesn't ICE when processing associated const (field expr).
+
+pub fn f() {
+    trait Trait {}
+    impl Trait {
+        const FLAG: u32 = bogus.field; //~ ERROR cannot find value `bogus`
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/save-analysis/issue-59134-0.stderr b/src/test/ui/save-analysis/issue-59134-0.stderr
new file mode 100644 (file)
index 0000000..4e9b2e6
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0425]: cannot find value `bogus` in this scope
+  --> $DIR/issue-59134-0.rs:8:27
+   |
+LL |         const FLAG: u32 = bogus.field;
+   |                           ^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/save-analysis/issue-59134-1.rs b/src/test/ui/save-analysis/issue-59134-1.rs
new file mode 100644 (file)
index 0000000..3cb6297
--- /dev/null
@@ -0,0 +1,12 @@
+// compile-flags: -Zsave-analysis
+
+// Check that this doesn't ICE when processing associated const (type).
+
+fn func() {
+    trait Trait {
+        type MyType;
+        const CONST: Self::MyType = bogus.field; //~ ERROR cannot find value `bogus`
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/save-analysis/issue-59134-1.stderr b/src/test/ui/save-analysis/issue-59134-1.stderr
new file mode 100644 (file)
index 0000000..bdc335e
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0425]: cannot find value `bogus` in this scope
+  --> $DIR/issue-59134-1.rs:8:37
+   |
+LL |         const CONST: Self::MyType = bogus.field;
+   |                                     ^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/traits/cycle-cache-err-60010.rs b/src/test/ui/traits/cycle-cache-err-60010.rs
new file mode 100644 (file)
index 0000000..45aa1b3
--- /dev/null
@@ -0,0 +1,71 @@
+// Test that we properly detect the cycle amongst the traits
+// here and report an error.
+
+use std::panic::RefUnwindSafe;
+
+trait Database {
+    type Storage;
+}
+trait HasQueryGroup {}
+trait Query<DB> {
+    type Data;
+}
+trait SourceDatabase {
+    fn parse(&self) {
+        loop {}
+    }
+}
+
+struct ParseQuery;
+struct RootDatabase {
+    _runtime: Runtime<RootDatabase>,
+}
+struct Runtime<DB: Database> {
+    _storage: Box<DB::Storage>,
+}
+struct SalsaStorage {
+    _parse: <ParseQuery as Query<RootDatabase>>::Data, //~ ERROR overflow
+}
+
+impl Database for RootDatabase { //~ ERROR overflow
+    type Storage = SalsaStorage;
+}
+impl HasQueryGroup for RootDatabase {}
+impl<DB> Query<DB> for ParseQuery
+where
+    DB: SourceDatabase,
+    DB: Database,
+{
+    type Data = RootDatabase;
+}
+impl<T> SourceDatabase for T
+where
+    T: RefUnwindSafe,
+    T: HasQueryGroup,
+{
+}
+
+pub(crate) fn goto_implementation(db: &RootDatabase) -> u32 {
+    // This is not satisfied:
+    //
+    // - `RootDatabase: SourceDatabase`
+    //   - requires `RootDatabase: RefUnwindSafe` + `RootDatabase: HasQueryGroup`
+    // - `RootDatabase: RefUnwindSafe`
+    //   - requires `Runtime<RootDatabase>: RefUnwindSafe`
+    // - `Runtime<RootDatabase>: RefUnwindSafe`
+    //   - requires `DB::Storage: RefUnwindSafe` (`SalsaStorage: RefUnwindSafe`)
+    // - `SalsaStorage: RefUnwindSafe`
+    //    - requires `<ParseQuery as Query<RootDatabase>>::Data: RefUnwindSafe`,
+    //      which means `ParseQuery: Query<RootDatabase>`
+    // - `ParseQuery: Query<RootDatabase>`
+    //    - requires `RootDatabase: SourceDatabase`,
+    // - `RootDatabase: SourceDatabase` is already on the stack, so we have a
+    //   cycle with non-coinductive participants
+    //
+    // we used to fail to report an error here because we got the
+    // caching wrong.
+    SourceDatabase::parse(db);
+    22
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/cycle-cache-err-60010.stderr b/src/test/ui/traits/cycle-cache-err-60010.stderr
new file mode 100644 (file)
index 0000000..9192f7b
--- /dev/null
@@ -0,0 +1,20 @@
+error[E0275]: overflow evaluating the requirement `RootDatabase: SourceDatabase`
+  --> $DIR/cycle-cache-err-60010.rs:27:5
+   |
+LL |     _parse: <ParseQuery as Query<RootDatabase>>::Data,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: required because of the requirements on the impl of `Query<RootDatabase>` for `ParseQuery`
+
+error[E0275]: overflow evaluating the requirement `RootDatabase: SourceDatabase`
+  --> $DIR/cycle-cache-err-60010.rs:30:6
+   |
+LL | impl Database for RootDatabase {
+   |      ^^^^^^^^
+   |
+   = note: required because of the requirements on the impl of `Query<RootDatabase>` for `ParseQuery`
+   = note: required because it appears within the type `SalsaStorage`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0275`.
index 3710ec59962295336ab4aed100267b584dd7df7d..ad3269c4b510b94b7c0082f4bb341bee6ed1eca4 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 3710ec59962295336ab4aed100267b584dd7df7d
+Subproject commit ad3269c4b510b94b7c0082f4bb341bee6ed1eca4
index 10b8133326bba2f798aa6c4506bb0687dbe5e804..b335fe3ae185a270d17057dcc7adfb2781c9d215 100644 (file)
@@ -2217,9 +2217,7 @@ fn run_assembly_test(&self) {
 
     fn charset() -> &'static str {
         // FreeBSD 10.1 defaults to GDB 6.1.1 which doesn't support "auto" charset
-        if cfg!(target_os = "bitrig") {
-            "auto"
-        } else if cfg!(target_os = "freebsd") {
+        if cfg!(target_os = "freebsd") {
             "ISO-8859-1"
         } else {
             "UTF-8"
@@ -2670,8 +2668,7 @@ fn run_rmake_test(&self) {
         create_dir_all(&tmpdir).unwrap();
 
         let host = &self.config.host;
-        let make = if host.contains("bitrig")
-            || host.contains("dragonfly")
+        let make = if host.contains("dragonfly")
             || host.contains("freebsd")
             || host.contains("netbsd")
             || host.contains("openbsd")
index adc1224bcd36738b42be469dfe3cf32d59d557c5..8caf5ca00f5053638f6ded0bfcdf298c814d325f 100644 (file)
@@ -9,7 +9,6 @@
 const OS_TABLE: &'static [(&'static str, &'static str)] = &[
     ("android", "android"),
     ("androideabi", "android"),
-    ("bitrig", "bitrig"),
     ("cloudabi", "cloudabi"),
     ("cuda", "cuda"),
     ("darwin", "macos"),
index 053aa694990a212ad8942dd72101ede23597c0e9..bc0c76d861a178911f3f506196a7404eda1e690d 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 053aa694990a212ad8942dd72101ede23597c0e9
+Subproject commit bc0c76d861a178911f3f506196a7404eda1e690d