]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #63779 - Centril:rollup-sx96dli, r=Centril
authorbors <bors@rust-lang.org>
Wed, 21 Aug 2019 11:40:23 +0000 (11:40 +0000)
committerbors <bors@rust-lang.org>
Wed, 21 Aug 2019 11:40:23 +0000 (11:40 +0000)
Rollup of 7 pull requests

Successful merges:

 - #63721 (Do not emit JSON dumps of diagnostic codes)
 - #63753 (Bump toml dependency.)
 - #63755 (Use dedicated type for spans in pre-expansion gating.)
 - #63759 (Allow 'default async fn' to parse.)
 - #63760 (Update books)
 - #63762 (`async_await` was stabilized in 1.39.0, not 1.38.0.)
 - #63766 (Remove some duplication when resolving constants)

Failed merges:

r? @ghost

24 files changed:
Cargo.lock
src/bootstrap/Cargo.toml
src/bootstrap/doc.rs
src/bootstrap/test.rs
src/doc/embedded-book
src/doc/nomicon
src/doc/reference
src/doc/rust-by-example
src/librustc/ty/relate.rs
src/librustc/ty/sty.rs
src/libsyntax/diagnostics/metadata.rs [deleted file]
src/libsyntax/diagnostics/plugin.rs
src/libsyntax/feature_gate.rs
src/libsyntax/lib.rs
src/libsyntax/parse/attr.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser/expr.rs
src/libsyntax/parse/parser/item.rs
src/libsyntax/parse/parser/pat.rs
src/test/ui/specialization/issue-63716-parse-async.rs [new file with mode: 0644]
src/tools/build-manifest/Cargo.toml
src/tools/error_index_generator/Cargo.toml
src/tools/error_index_generator/build.rs [new file with mode: 0644]
src/tools/error_index_generator/main.rs

index 660f2ba237008f0d42ff1b7d637786edcfe58d42..06c455b3c910d40fcecd06a0ce2fd8bc4a1f9259 100644 (file)
@@ -185,7 +185,7 @@ dependencies = [
  "serde",
  "serde_json",
  "time",
- "toml 0.4.10",
+ "toml",
 ]
 
 [[package]]
@@ -202,7 +202,7 @@ name = "build-manifest"
 version = "0.1.0"
 dependencies = [
  "serde",
- "toml 0.4.10",
+ "toml",
 ]
 
 [[package]]
@@ -316,7 +316,7 @@ dependencies = [
  "tar",
  "tempfile",
  "termcolor",
- "toml 0.5.3",
+ "toml",
  "unicode-width",
  "url 2.1.0",
  "walkdir",
@@ -442,7 +442,7 @@ dependencies = [
  "semver",
  "serde",
  "smallvec",
- "toml 0.5.3",
+ "toml",
  "unicode-normalization",
  "url 2.1.0",
 ]
@@ -946,6 +946,7 @@ name = "error_index_generator"
 version = "0.0.0"
 dependencies = [
  "rustdoc",
+ "walkdir",
 ]
 
 [[package]]
@@ -1785,7 +1786,7 @@ dependencies = [
  "serde_json",
  "shlex",
  "tempfile",
- "toml 0.5.3",
+ "toml",
  "toml-query",
 ]
 
@@ -2760,7 +2761,7 @@ dependencies = [
  "tokio",
  "tokio-process",
  "tokio-timer",
- "toml 0.5.3",
+ "toml",
  "url 1.7.2",
  "walkdir",
 ]
@@ -3590,7 +3591,7 @@ dependencies = [
  "serde_json",
  "structopt",
  "term 0.6.0",
- "toml 0.5.3",
+ "toml",
  "unicode-segmentation",
  "unicode-width",
  "unicode_categories",
@@ -4382,15 +4383,6 @@ dependencies = [
  "tokio-reactor",
 ]
 
-[[package]]
-name = "toml"
-version = "0.4.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
-dependencies = [
- "serde",
-]
-
 [[package]]
 name = "toml"
 version = "0.5.3"
@@ -4411,7 +4403,7 @@ dependencies = [
  "is-match",
  "lazy_static 1.3.0",
  "regex",
- "toml 0.5.3",
+ "toml",
  "toml-query_derive",
 ]
 
index 589ee9276a5a3be6a406e19d495bfa1de7b5e4b9..c27c318f5ad07201703bd2a424fc5caed3ac80f3 100644 (file)
@@ -44,7 +44,7 @@ cc = "1.0.35"
 libc = "0.2"
 serde = { version = "1.0.8", features = ["derive"] }
 serde_json = "1.0.2"
-toml = "0.4"
+toml = "0.5"
 lazy_static = "1.3.0"
 time = "0.1"
 petgraph = "0.4.13"
index 36229720e42cd5f993c4338c03f97e958126b04d..4f96c12fc1dddb3b2bf856bc503412a2fca26c6e 100644 (file)
@@ -825,8 +825,7 @@ fn run(self, builder: &Builder<'_>) {
         index.arg(crate::channel::CFG_RELEASE_NUM);
 
         // FIXME: shouldn't have to pass this env var
-        index.env("CFG_BUILD", &builder.config.build)
-             .env("RUSTC_ERROR_METADATA_DST", builder.extended_error_dir());
+        index.env("CFG_BUILD", &builder.config.build);
 
         builder.run(&mut index);
     }
index c2c134bfd1d7da7d1a7225e448a62810e9873d74..87bd5cbacfffaccaf59c342fae379a2b91a58b55 100644 (file)
@@ -1535,8 +1535,7 @@ fn run(self, builder: &Builder<'_>) {
         );
         tool.arg("markdown")
             .arg(&output)
-            .env("CFG_BUILD", &builder.config.build)
-            .env("RUSTC_ERROR_METADATA_DST", builder.extended_error_dir());
+            .env("CFG_BUILD", &builder.config.build);
 
         builder.info(&format!("Testing error-index stage{}", compiler.stage));
         let _time = util::timeit(&builder);
index c5da1e11915d3f28266168baaf55822f7e3fe999..432ca26686c11d396eed6a59499f93ce1bf2433c 160000 (submodule)
@@ -1 +1 @@
-Subproject commit c5da1e11915d3f28266168baaf55822f7e3fe999
+Subproject commit 432ca26686c11d396eed6a59499f93ce1bf2433c
index 8a7d05615e5bc0a7fb961b4919c44f5221ee54da..38b9a76bc8b59ac862663807fc51c9b757337fd6 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 8a7d05615e5bc0a7fb961b4919c44f5221ee54da
+Subproject commit 38b9a76bc8b59ac862663807fc51c9b757337fd6
index b4b3536839042a6743fc76f0d9ad2a812020aeaa..d191a0cdd3b92648e0f1e53b13140a14677cc65b 160000 (submodule)
@@ -1 +1 @@
-Subproject commit b4b3536839042a6743fc76f0d9ad2a812020aeaa
+Subproject commit d191a0cdd3b92648e0f1e53b13140a14677cc65b
index f2c15ba5ee89ae9469a2cf60494977749901d764..580839d90aacd537f0293697096fa8355bc4e673 160000 (submodule)
@@ -1 +1 @@
-Subproject commit f2c15ba5ee89ae9469a2cf60494977749901d764
+Subproject commit 580839d90aacd537f0293697096fa8355bc4e673
index 945e3e158eafb016c71bed74fdc8547e36e2db22..565447dd7e1afd7fc0fc63aff0b9e401383b70b3 100644 (file)
@@ -8,7 +8,7 @@
 use crate::ty::subst::{Kind, UnpackedKind, SubstsRef};
 use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
 use crate::ty::error::{ExpectedFound, TypeError};
-use crate::mir::interpret::{ConstValue, Scalar, GlobalId};
+use crate::mir::interpret::{ConstValue, Scalar};
 use std::rc::Rc;
 use std::iter;
 use rustc_target::spec::abi;
@@ -551,26 +551,8 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
     let tcx = relation.tcx();
 
     let eagerly_eval = |x: &'tcx ty::Const<'tcx>| {
-        if let ConstValue::Unevaluated(def_id, substs) = x.val {
-            // FIXME(eddyb) get the right param_env.
-            let param_env = ty::ParamEnv::empty();
-            if !substs.has_local_value() {
-                let instance = ty::Instance::resolve(
-                    tcx.global_tcx(),
-                    param_env,
-                    def_id,
-                    substs,
-                );
-                if let Some(instance) = instance {
-                    let cid = GlobalId {
-                        instance,
-                        promoted: None,
-                    };
-                    if let Ok(ct) = tcx.const_eval(param_env.and(cid)) {
-                        return ct.val;
-                    }
-                }
-            }
+        if !x.val.has_local_value() {
+            return x.eval(tcx, relation.param_env()).val;
         }
         x.val
     };
index 2b173068b38e4a610e32c546d502a9c6d3c0a5ad..da66fdf5b1b1b724f9aba3042eeb37d224648b00 100644 (file)
@@ -2299,23 +2299,33 @@ pub fn try_eval_bits(
         assert_eq!(self.ty, ty);
         // if `ty` does not depend on generic parameters, use an empty param_env
         let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size;
+        self.eval(tcx, param_env).val.try_to_bits(size)
+    }
+
+    #[inline]
+    pub fn eval(
+        &self,
+        tcx: TyCtxt<'tcx>,
+        param_env: ParamEnv<'tcx>,
+    ) -> &Const<'tcx> {
+        // FIXME(const_generics): this doesn't work right now,
+        // because it tries to relate an `Infer` to a `Param`.
         match self.val {
-            // FIXME(const_generics): this doesn't work right now,
-            // because it tries to relate an `Infer` to a `Param`.
             ConstValue::Unevaluated(did, substs) => {
                 // if `substs` has no unresolved components, use and empty param_env
                 let (param_env, substs) = param_env.with_reveal_all().and(substs).into_parts();
                 // try to resolve e.g. associated constants to their definition on an impl
-                let instance = ty::Instance::resolve(tcx, param_env, did, substs)?;
+                let instance = match ty::Instance::resolve(tcx, param_env, did, substs) {
+                    Some(instance) => instance,
+                    None => return self,
+                };
                 let gid = GlobalId {
                     instance,
                     promoted: None,
                 };
-                let evaluated = tcx.const_eval(param_env.and(gid)).ok()?;
-                evaluated.val.try_to_bits(size)
+                tcx.const_eval(param_env.and(gid)).unwrap_or(self)
             },
-            // otherwise just extract a `ConstValue`'s bits if possible
-            _ => self.val.try_to_bits(size),
+            _ => self,
         }
     }
 
diff --git a/src/libsyntax/diagnostics/metadata.rs b/src/libsyntax/diagnostics/metadata.rs
deleted file mode 100644 (file)
index 53f37bb..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-//! This module contains utilities for outputting metadata for diagnostic errors.
-//!
-//! Each set of errors is mapped to a metadata file by a name, which is
-//! currently always a crate name.
-
-use std::collections::BTreeMap;
-use std::env;
-use std::fs::{remove_file, create_dir_all, File};
-use std::io::Write;
-use std::path::PathBuf;
-use std::error::Error;
-use rustc_serialize::json::as_json;
-
-use syntax_pos::{Span, FileName};
-
-use crate::ext::base::ExtCtxt;
-use crate::diagnostics::plugin::{ErrorMap, ErrorInfo};
-
-/// JSON encodable/decodable version of `ErrorInfo`.
-#[derive(PartialEq, RustcDecodable, RustcEncodable)]
-pub struct ErrorMetadata {
-    pub description: Option<String>,
-    pub use_site: Option<ErrorLocation>
-}
-
-/// Mapping from error codes to metadata that can be (de)serialized.
-pub type ErrorMetadataMap = BTreeMap<String, ErrorMetadata>;
-
-/// JSON encodable error location type with filename and line number.
-#[derive(PartialEq, RustcDecodable, RustcEncodable)]
-pub struct ErrorLocation {
-    pub filename: FileName,
-    pub line: usize
-}
-
-impl ErrorLocation {
-    /// Creates an error location from a span.
-    pub fn from_span(ecx: &ExtCtxt<'_>, sp: Span) -> ErrorLocation {
-        let loc = ecx.source_map().lookup_char_pos(sp.lo());
-        ErrorLocation {
-            filename: loc.file.name.clone(),
-            line: loc.line
-        }
-    }
-}
-
-/// Gets the directory where metadata for a given `prefix` should be stored.
-///
-/// See `output_metadata`.
-pub fn get_metadata_dir(prefix: &str) -> PathBuf {
-    env::var_os("RUSTC_ERROR_METADATA_DST")
-        .map(PathBuf::from)
-        .expect("env var `RUSTC_ERROR_METADATA_DST` isn't set")
-        .join(prefix)
-}
-
-/// Map `name` to a path in the given directory: <directory>/<name>.json
-fn get_metadata_path(directory: PathBuf, name: &str) -> PathBuf {
-    directory.join(format!("{}.json", name))
-}
-
-/// Write metadata for the errors in `err_map` to disk, to a file corresponding to `prefix/name`.
-///
-/// For our current purposes the prefix is the target architecture and the name is a crate name.
-/// If an error occurs steps will be taken to ensure that no file is created.
-pub fn output_metadata(ecx: &ExtCtxt<'_>, prefix: &str, name: &str, err_map: &ErrorMap)
-    -> Result<(), Box<dyn Error>>
-{
-    // Create the directory to place the file in.
-    let metadata_dir = get_metadata_dir(prefix);
-    create_dir_all(&metadata_dir)?;
-
-    // Open the metadata file.
-    let metadata_path = get_metadata_path(metadata_dir, name);
-    let mut metadata_file = File::create(&metadata_path)?;
-
-    // Construct a serializable map.
-    let json_map = err_map.iter().map(|(k, &ErrorInfo { description, use_site })| {
-        let key = k.as_str().to_string();
-        let value = ErrorMetadata {
-            description: description.map(|n| n.as_str().to_string()),
-            use_site: use_site.map(|sp| ErrorLocation::from_span(ecx, sp))
-        };
-        (key, value)
-    }).collect::<ErrorMetadataMap>();
-
-    // Write the data to the file, deleting it if the write fails.
-    let result = write!(&mut metadata_file, "{}", as_json(&json_map));
-    if result.is_err() {
-        remove_file(&metadata_path)?;
-    }
-    Ok(result?)
-}
index 9618b5acfb0f18d8b72d8e07b385a265398507c9..e9a55af52e8780001625dbd79a97fd9632edbe62 100644 (file)
@@ -1,5 +1,4 @@
 use std::collections::BTreeMap;
-use std::env;
 
 use crate::ast::{self, Ident, Name};
 use crate::source_map;
@@ -12,8 +11,6 @@
 use smallvec::smallvec;
 use syntax_pos::Span;
 
-use crate::diagnostics::metadata::output_metadata;
-
 pub use errors::*;
 
 // Maximum width of any line in an extended error description (inclusive).
@@ -127,36 +124,13 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>,
                                           token_tree: &[TokenTree])
                                           -> Box<dyn MacResult+'cx> {
     assert_eq!(token_tree.len(), 3);
-    let (crate_name, ident) = match (&token_tree[0], &token_tree[2]) {
-        (
-            // Crate name.
-            &TokenTree::Token(Token { kind: token::Ident(crate_name, _), .. }),
-            // DIAGNOSTICS ident.
-            &TokenTree::Token(Token { kind: token::Ident(name, _), span })
-        ) => (crate_name, Ident::new(name, span)),
+    let ident = match &token_tree[2] {
+        // DIAGNOSTICS ident.
+        &TokenTree::Token(Token { kind: token::Ident(name, _), span })
+        => Ident::new(name, span),
         _ => unreachable!()
     };
 
-    // Output error metadata to `tmp/extended-errors/<target arch>/<crate name>.json`
-    if let Ok(target_triple) = env::var("CFG_COMPILER_HOST_TRIPLE") {
-        ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
-            if let Err(e) = output_metadata(ecx,
-                                            &target_triple,
-                                            &crate_name.as_str(),
-                                            diagnostics) {
-                ecx.span_bug(span, &format!(
-                    "error writing metadata for triple `{}` and crate `{}`, error: {}, \
-                     cause: {:?}",
-                    target_triple, crate_name, e.description(), e.source()
-                ));
-            }
-        });
-    } else {
-        ecx.span_err(span, &format!(
-            "failed to write metadata for crate `{}` because $CFG_COMPILER_HOST_TRIPLE is not set",
-            crate_name));
-    }
-
     // Construct the output expression.
     let (count, expr) =
         ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
index bce0b07db1c233b3f84bd207eb78dadf83bbc05c..fad4f3da3de70b2d668a132b750149243a7dbca1 100644 (file)
@@ -855,7 +855,7 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Allows `const _: TYPE = VALUE`.
     (accepted, underscore_const_names, "1.37.0", Some(54912), None),
     // Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
-    (accepted, async_await, "1.38.0", Some(50547), None),
+    (accepted, async_await, "1.39.0", Some(50547), None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: accepted features
@@ -2423,16 +2423,19 @@ pub fn check_crate(krate: &ast::Crate,
     };
 
     macro_rules! gate_all {
+        ($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); };
         ($spans:ident, $gate:ident, $msg:literal) => {
-            for span in &*sess.$spans.borrow() { gate_feature!(&ctx, $gate, *span, $msg); }
+            for span in &*sess.gated_spans.$spans.borrow() {
+                gate_feature!(&ctx, $gate, *span, $msg);
+            }
         }
     }
 
-    gate_all!(param_attr_spans, param_attrs, "attributes on function parameters are unstable");
-    gate_all!(let_chains_spans, let_chains, "`let` expressions in this position are experimental");
-    gate_all!(async_closure_spans, async_closure, "async closures are unstable");
-    gate_all!(yield_spans, generators, "yield syntax is experimental");
-    gate_all!(or_pattern_spans, or_patterns, "or-patterns syntax is experimental");
+    gate_all!(param_attrs, "attributes on function parameters are unstable");
+    gate_all!(let_chains, "`let` expressions in this position are experimental");
+    gate_all!(async_closure, "async closures are unstable");
+    gate_all!(yields, generators, "yield syntax is experimental");
+    gate_all!(or_patterns, "or-patterns syntax is experimental");
 
     let visitor = &mut PostExpansionVisitor {
         context: &ctx,
index 8ac48d8d74a42dcf463854e36358a07010a59ee8..1741932c1b80e30f86abfe47d345b37678f24068 100644 (file)
@@ -124,7 +124,6 @@ pub mod diagnostics {
     #[macro_use]
     pub mod macros;
     pub mod plugin;
-    pub mod metadata;
 }
 
 // N.B., this module needs to be declared first so diagnostics are
index a42da1123600a999fb6ac1343a2fa6cd3524f52f..c703058e7952de818f5dbb79ad4b45eeaaf1bc26 100644 (file)
@@ -21,9 +21,8 @@ enum InnerAttributeParsePolicy<'a> {
 impl<'a> Parser<'a> {
     crate fn parse_arg_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
         let attrs = self.parse_outer_attributes()?;
-        attrs.iter().for_each(|a|
-            self.sess.param_attr_spans.borrow_mut().push(a.span)
-        );
+        self.sess.gated_spans.param_attrs.borrow_mut()
+            .extend(attrs.iter().map(|a| a.span));
         Ok(attrs)
     }
 
index b1f3612a839a2cb41bbe106053a9187257ef7ae6..b1af4806e2d787dde3b9f17b200550fc42931834 100644 (file)
 
 pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
 
+/// Collected spans during parsing for places where a certain feature was
+/// used and should be feature gated accordingly in `check_crate`.
+#[derive(Default)]
+pub struct GatedSpans {
+    /// Spans collected for gating `param_attrs`, e.g. `fn foo(#[attr] x: u8) {}`.
+    pub param_attrs: Lock<Vec<Span>>,
+    /// Spans collected for gating `let_chains`, e.g. `if a && let b = c {}`.
+    pub let_chains: Lock<Vec<Span>>,
+    /// Spans collected for gating `async_closure`, e.g. `async || ..`.
+    pub async_closure: Lock<Vec<Span>>,
+    /// Spans collected for gating `yield e?` expressions (`generators` gate).
+    pub yields: Lock<Vec<Span>>,
+    /// Spans collected for gating `or_patterns`, e.g. `Some(Foo | Bar)`.
+    pub or_patterns: Lock<Vec<Span>>,
+}
+
 /// Info about a parsing session.
 pub struct ParseSess {
     pub span_diagnostic: Handler,
@@ -58,16 +74,8 @@ pub struct ParseSess {
     /// operation token that followed it, but that the parser cannot identify without further
     /// analysis.
     pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
-    pub param_attr_spans: Lock<Vec<Span>>,
-    // Places where `let` exprs were used and should be feature gated according to `let_chains`.
-    pub let_chains_spans: Lock<Vec<Span>>,
-    // Places where `async || ..` exprs were used and should be feature gated.
-    pub async_closure_spans: Lock<Vec<Span>>,
-    // Places where `yield e?` exprs were used and should be feature gated.
-    pub yield_spans: Lock<Vec<Span>>,
     pub injected_crate_name: Once<Symbol>,
-    // Places where or-patterns e.g. `Some(Foo | Bar)` were used and should be feature gated.
-    pub or_pattern_spans: Lock<Vec<Span>>,
+    pub gated_spans: GatedSpans,
 }
 
 impl ParseSess {
@@ -93,12 +101,8 @@ pub fn with_span_handler(handler: Handler, source_map: Lrc<SourceMap>) -> ParseS
             buffered_lints: Lock::new(vec![]),
             edition: ExpnId::root().expn_data().edition,
             ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
-            param_attr_spans: Lock::new(Vec::new()),
-            let_chains_spans: Lock::new(Vec::new()),
-            async_closure_spans: Lock::new(Vec::new()),
-            yield_spans: Lock::new(Vec::new()),
             injected_crate_name: Once::new(),
-            or_pattern_spans: Lock::new(Vec::new()),
+            gated_spans: GatedSpans::default(),
         }
     }
 
index ccc6bd1506709155920216bfc0c00842d3ce522a..5da9b75d53b045cfb2b8deb6bc1ee6ab56322197 100644 (file)
@@ -999,7 +999,7 @@ macro_rules! parse_lit {
                     }
 
                     let span = lo.to(hi);
-                    self.sess.yield_spans.borrow_mut().push(span);
+                    self.sess.gated_spans.yields.borrow_mut().push(span);
                 } else if self.eat_keyword(kw::Let) {
                     return self.parse_let_expr(attrs);
                 } else if is_span_rust_2018 && self.eat_keyword(kw::Await) {
@@ -1111,7 +1111,7 @@ fn parse_lambda_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr
         };
         if asyncness.is_async() {
             // Feature gate `async ||` closures.
-            self.sess.async_closure_spans.borrow_mut().push(self.prev_span);
+            self.sess.gated_spans.async_closure.borrow_mut().push(self.prev_span);
         }
 
         let capture_clause = self.parse_capture_clause();
@@ -1234,7 +1234,7 @@ fn parse_cond_expr(&mut self) -> PResult<'a, P<Expr>> {
 
         if let ExprKind::Let(..) = cond.node {
             // Remove the last feature gating of a `let` expression since it's stable.
-            let last = self.sess.let_chains_spans.borrow_mut().pop();
+            let last = self.sess.gated_spans.let_chains.borrow_mut().pop();
             debug_assert_eq!(cond.span, last.unwrap());
         }
 
@@ -1252,7 +1252,7 @@ fn parse_let_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>>
             |this| this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into())
         )?;
         let span = lo.to(expr.span);
-        self.sess.let_chains_spans.borrow_mut().push(span);
+        self.sess.gated_spans.let_chains.borrow_mut().push(span);
         Ok(self.mk_expr(span, ExprKind::Let(pats, expr), attrs))
     }
 
index 72819c9966035223fe24121f7c081470176dd6fe..03d7e9221238245ab61014040fb4330bdb5f4643 100644 (file)
@@ -825,6 +825,7 @@ fn parse_defaultness(&mut self) -> Defaultness {
             self.is_keyword_ahead(1, &[
                 kw::Impl,
                 kw::Const,
+                kw::Async,
                 kw::Fn,
                 kw::Unsafe,
                 kw::Extern,
index fd458aec743315792463c1e3d0024734b6d3a5a3..8cfa6abbe6270e7181a337791940c90f98e5bfe1 100644 (file)
@@ -123,7 +123,7 @@ fn parse_pat_with_or(&mut self, expected: Option<&'static str>) -> PResult<'a, P
 
         let or_pattern_span = lo.to(self.prev_span);
 
-        self.sess.or_pattern_spans.borrow_mut().push(or_pattern_span);
+        self.sess.gated_spans.or_patterns.borrow_mut().push(or_pattern_span);
 
         Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats)))
     }
diff --git a/src/test/ui/specialization/issue-63716-parse-async.rs b/src/test/ui/specialization/issue-63716-parse-async.rs
new file mode 100644 (file)
index 0000000..c3764ff
--- /dev/null
@@ -0,0 +1,14 @@
+// Ensure that `default async fn` will parse.
+// See issue #63716 for details.
+
+// check-pass
+// edition:2018
+
+#![feature(specialization)]
+
+fn main() {}
+
+#[cfg(FALSE)]
+impl Foo for Bar {
+    default async fn baz() {}
+}
index 63b6399bb9034e28daa466e59825593b10e1f443..c364479d8db13251be3caf4bc2a249b8c84df98d 100644 (file)
@@ -5,5 +5,5 @@ authors = ["Alex Crichton <alex@alexcrichton.com>"]
 edition = "2018"
 
 [dependencies]
-toml = "0.4"
+toml = "0.5"
 serde = { version = "1.0", features = ["derive"] }
index 116be234f3ceb882d1a02f92626b61bdee58ee51..992af261b8352f1495f91e8f3d3d01515df40440 100644 (file)
@@ -3,10 +3,14 @@ authors = ["The Rust Project Developers"]
 name = "error_index_generator"
 version = "0.0.0"
 edition = "2018"
+build = "build.rs"
 
 [dependencies]
 rustdoc = { path = "../../librustdoc" }
 
+[build-dependencies]
+walkdir = "2"
+
 [[bin]]
 name = "error_index_generator"
 path = "main.rs"
diff --git a/src/tools/error_index_generator/build.rs b/src/tools/error_index_generator/build.rs
new file mode 100644 (file)
index 0000000..2ac7351
--- /dev/null
@@ -0,0 +1,64 @@
+use walkdir::WalkDir;
+use std::path::PathBuf;
+use std::{env, fs};
+
+fn main() {
+    // The src directory (we are in src/tools/error_index_generator)
+    // Note that we could skip one of the .. but this ensures we at least loosely find the right
+    // directory.
+    let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
+    let dest = out_dir.join("error_codes.rs");
+    let mut idx = 0;
+    for entry in WalkDir::new("../../../src") {
+        let entry = entry.unwrap();
+        if entry.file_name() == "error_codes.rs" {
+            println!("cargo:rerun-if-changed={}", entry.path().to_str().unwrap());
+            let file = fs::read_to_string(entry.path()).unwrap()
+                .replace("use syntax::{register_diagnostics, register_long_diagnostics};", "")
+                .replace("use syntax::register_diagnostics;", "")
+                .replace("use syntax::register_long_diagnostics;", "");
+            let contents = format!("(|| {{\n{}\n}})();", file);
+
+            fs::write(&out_dir.join(&format!("error_{}.rs", idx)), &contents).unwrap();
+
+            idx += 1;
+        }
+    }
+
+    let mut all = String::new();
+    all.push_str("fn register_all() -> Vec<(&'static str, Option<&'static str>)> {\n");
+    all.push_str("let mut long_codes: Vec<(&'static str, Option<&'static str>)> = Vec::new();\n");
+    all.push_str(r#"
+macro_rules! register_diagnostics {
+    ($($code:tt),*) => {{
+        long_codes.extend([$(
+            stringify!($code),
+        )*].iter().cloned().map(|s| (s, None)).collect::<Vec<_>>());
+    }};
+    ($($code:tt),*,) => {{
+        long_codes.extend([$(
+            stringify!($code),
+        )*].iter().cloned().map(|s| (s, None)));
+    }}
+}
+
+macro_rules! register_long_diagnostics {
+    ($($code:tt: $description:tt),*) => {
+        {long_codes.extend([$(
+            (stringify!($code), Some(stringify!($description))),
+        )*].iter());}
+    };
+    ($($code:tt: $description:tt),*,) => {
+        {long_codes.extend([$(
+            (stringify!($code), Some(stringify!($description))),
+        )*].iter());}
+    }
+}"#);
+    for idx in 0..idx {
+        all.push_str(&format!(r#"include!(concat!(env!("OUT_DIR"), "/error_{}.rs"));"#, idx));
+    }
+    all.push_str("\nlong_codes\n");
+    all.push_str("}\n");
+
+    fs::write(&dest, all).unwrap();
+}
index a9d1d9997f6ef3f7cfc18ce3ce052e3fc2a24a52..c4826a0c31d6cb457500c33b9f4f7a9b28df36d4 100644 (file)
@@ -2,22 +2,26 @@
 
 extern crate env_logger;
 extern crate syntax;
-extern crate serialize as rustc_serialize;
 
 use std::collections::BTreeMap;
 use std::env;
 use std::error::Error;
-use std::fs::{self, read_dir, File};
+use std::fs::File;
 use std::io::Write;
 use std::path::Path;
 use std::path::PathBuf;
 use std::cell::RefCell;
 
 use syntax::edition::DEFAULT_EDITION;
-use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};
 
 use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, Playground};
-use rustc_serialize::json;
+
+pub struct ErrorMetadata {
+    pub description: Option<String>,
+}
+
+/// Mapping from error codes to metadata that can be (de)serialized.
+pub type ErrorMetadataMap = BTreeMap<String, ErrorMetadata>;
 
 enum OutputFormat {
     HTML(HTMLFormatter),
@@ -80,11 +84,7 @@ fn error_code_block(&self, output: &mut dyn Write, info: &ErrorMetadata,
             Some(_) => "error-described",
             None => "error-undescribed",
         };
-        let use_desc = match info.use_site {
-            Some(_) => "error-used",
-            None => "error-unused",
-        };
-        write!(output, "<div class=\"{} {}\">", desc_desc, use_desc)?;
+        write!(output, "<div class=\"{}\">", desc_desc)?;
 
         // Error title (with self-link).
         write!(output,
@@ -199,25 +199,6 @@ fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
     }
 }
 
-/// Loads all the metadata files from `metadata_dir` into an in-memory map.
-fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<dyn Error>> {
-    let mut all_errors = BTreeMap::new();
-
-    for entry in read_dir(metadata_dir)? {
-        let path = entry?.path();
-
-        let metadata_str = fs::read_to_string(&path)?;
-
-        let some_errors: ErrorMetadataMap = json::decode(&metadata_str)?;
-
-        for (err_code, info) in some_errors {
-            all_errors.insert(err_code, info);
-        }
-    }
-
-    Ok(all_errors)
-}
-
 /// Output an HTML page for the errors in `err_map` to `output_path`.
 fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Path,
                                    formatter: T) -> Result<(), Box<dyn Error>> {
@@ -234,9 +215,13 @@ fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Pat
 }
 
 fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<dyn Error>> {
-    let build_arch = env::var("CFG_BUILD")?;
-    let metadata_dir = get_metadata_dir(&build_arch);
-    let err_map = load_all_errors(&metadata_dir)?;
+    let long_codes = register_all();
+    let mut err_map = BTreeMap::new();
+    for (code, desc) in long_codes {
+        err_map.insert(code.to_string(), ErrorMetadata {
+            description: desc.map(String::from),
+        });
+    }
     match format {
         OutputFormat::Unknown(s)  => panic!("Unknown output format: {}", s),
         OutputFormat::HTML(h)     => render_error_page(&err_map, dst, h)?,
@@ -272,3 +257,5 @@ fn main() {
         panic!("{}", e.description());
     }
 }
+
+include!(concat!(env!("OUT_DIR"), "/error_codes.rs"));