From 7df0052df8234be4c9075cec3c2d6414a28c87b1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 28 Nov 2020 16:11:25 +0100 Subject: [PATCH 1/3] Created NestedMetaItem::name_value_literal_span method --- compiler/rustc_ast/src/attr/mod.rs | 15 +++++++++++++++ compiler/rustc_attr/src/builtin.rs | 2 +- compiler/rustc_expand/src/expand.rs | 11 +++++------ compiler/rustc_middle/src/middle/limits.rs | 3 +-- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 2ff6573744442..30050002046e6 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -115,6 +115,10 @@ impl NestedMetaItem { pub fn is_meta_item_list(&self) -> bool { self.meta_item_list().is_some() } + + pub fn name_value_literal_span(&self) -> Option { + self.meta_item()?.name_value_literal_span() + } } impl Attribute { @@ -175,6 +179,13 @@ impl Attribute { pub fn is_value_str(&self) -> bool { self.value_str().is_some() } + + pub fn name_value_literal_span(&self) -> Option { + match self.kind { + AttrKind::Normal(ref item, _) => item.meta(self.span).and_then(|meta| meta.name_value_literal_span()), + AttrKind::DocComment(..) => None, + } + } } impl MetaItem { @@ -227,6 +238,10 @@ impl MetaItem { pub fn is_value_str(&self) -> bool { self.value_str().is_some() } + + pub fn name_value_literal_span(&self) -> Option { + Some(self.name_value_literal()?.span) + } } impl AttrItem { diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 364a3a1eeb5e7..bb7562bc80c7c 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -294,7 +294,7 @@ where or \"none\"", ) .span_label( - mi.name_value_literal().unwrap().span, + mi.name_value_literal_span().unwrap(), msg, ) .emit(); diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 4ba75c21cf058..37ff6b9b368e7 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1603,23 +1603,22 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { items.push(ast::NestedMetaItem::MetaItem(item)); } Err(e) => { - let lit = - it.meta_item().and_then(|item| item.name_value_literal()).unwrap(); + let lit_span = it.name_value_literal_span().unwrap(); if e.kind() == ErrorKind::InvalidData { self.cx .struct_span_err( - lit.span, + lit_span, &format!("{} wasn't a utf-8 file", filename.display()), ) - .span_label(lit.span, "contains invalid utf-8") + .span_label(lit_span, "contains invalid utf-8") .emit(); } else { let mut err = self.cx.struct_span_err( - lit.span, + lit_span, &format!("couldn't read {}: {}", filename.display(), e), ); - err.span_label(lit.span, "couldn't read file"); + err.span_label(lit_span, "couldn't read file"); err.emit(); } diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index 41342764ba773..61f850c2fc166 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -43,8 +43,7 @@ fn update_limit( let value_span = attr .meta() - .and_then(|meta| meta.name_value_literal().cloned()) - .map(|lit| lit.span) + .and_then(|meta| meta.name_value_literal_span()) .unwrap_or(attr.span); let error_str = match e.kind() { From 63816da5ed1abfe0c3b134dbf6710725d4416ee4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 28 Nov 2020 17:53:20 +0100 Subject: [PATCH 2/3] Improve some attributes error spans --- compiler/rustc_ast/src/attr/mod.rs | 4 +++- compiler/rustc_passes/src/check_attr.rs | 4 ++-- .../rustdoc-ui/check-doc-alias-attr.stderr | 24 +++++++++---------- .../rustdoc-ui/doc-alias-crate-level.stderr | 4 ++-- src/test/ui/check-doc-alias-attr.stderr | 24 +++++++++---------- src/test/ui/doc-alias-crate-level.stderr | 4 ++-- 6 files changed, 33 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 30050002046e6..22539bb1d9d19 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -182,7 +182,9 @@ impl Attribute { pub fn name_value_literal_span(&self) -> Option { match self.kind { - AttrKind::Normal(ref item, _) => item.meta(self.span).and_then(|meta| meta.name_value_literal_span()), + AttrKind::Normal(ref item, _) => { + item.meta(self.span).and_then(|meta| meta.name_value_literal_span()) + } AttrKind::DocComment(..) => None, } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 9c0234953bba9..c9e02d56f4b28 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -319,7 +319,7 @@ impl CheckAttrVisitor<'tcx> { self.tcx .sess .struct_span_err( - meta.span(), + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), &format!( "{:?} character isn't allowed in `#[doc(alias = \"...\")]`", c, @@ -332,7 +332,7 @@ impl CheckAttrVisitor<'tcx> { self.tcx .sess .struct_span_err( - meta.span(), + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), "`#[doc(alias = \"...\")]` cannot start or end with ' '", ) .emit(); diff --git a/src/test/rustdoc-ui/check-doc-alias-attr.stderr b/src/test/rustdoc-ui/check-doc-alias-attr.stderr index 8a729b02e72bf..3ba0ba6107531 100644 --- a/src/test/rustdoc-ui/check-doc-alias-attr.stderr +++ b/src/test/rustdoc-ui/check-doc-alias-attr.stderr @@ -17,42 +17,42 @@ LL | #[doc(alias("bar"))] | ^^^^^^^^^^^^ error: '\"' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:9:7 + --> $DIR/check-doc-alias-attr.rs:9:15 | LL | #[doc(alias = "\"")] - | ^^^^^^^^^^^^ + | ^^^^ error: '\n' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:10:7 + --> $DIR/check-doc-alias-attr.rs:10:15 | LL | #[doc(alias = "\n")] - | ^^^^^^^^^^^^ + | ^^^^ error: '\n' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:11:7 + --> $DIR/check-doc-alias-attr.rs:11:15 | LL | #[doc(alias = " - | _______^ + | _______________^ LL | | ")] | |_^ error: '\t' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:13:7 + --> $DIR/check-doc-alias-attr.rs:13:15 | LL | #[doc(alias = "\t")] - | ^^^^^^^^^^^^ + | ^^^^ error: `#[doc(alias = "...")]` cannot start or end with ' ' - --> $DIR/check-doc-alias-attr.rs:14:7 + --> $DIR/check-doc-alias-attr.rs:14:15 | LL | #[doc(alias = " hello")] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: `#[doc(alias = "...")]` cannot start or end with ' ' - --> $DIR/check-doc-alias-attr.rs:15:7 + --> $DIR/check-doc-alias-attr.rs:15:15 | LL | #[doc(alias = "hello ")] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: aborting due to 9 previous errors diff --git a/src/test/rustdoc-ui/doc-alias-crate-level.stderr b/src/test/rustdoc-ui/doc-alias-crate-level.stderr index fc14266cd714c..a58e91c5aa74a 100644 --- a/src/test/rustdoc-ui/doc-alias-crate-level.stderr +++ b/src/test/rustdoc-ui/doc-alias-crate-level.stderr @@ -1,8 +1,8 @@ error: '\'' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/doc-alias-crate-level.rs:5:7 + --> $DIR/doc-alias-crate-level.rs:5:15 | LL | #[doc(alias = "shouldn't work!")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ error: `#![doc(alias = "...")]` isn't allowed as a crate level attribute --> $DIR/doc-alias-crate-level.rs:3:8 diff --git a/src/test/ui/check-doc-alias-attr.stderr b/src/test/ui/check-doc-alias-attr.stderr index 2c417a3bb65b5..a92298d163380 100644 --- a/src/test/ui/check-doc-alias-attr.stderr +++ b/src/test/ui/check-doc-alias-attr.stderr @@ -17,42 +17,42 @@ LL | #[doc(alias("bar"))] | ^^^^^^^^^^^^ error: '\"' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:10:7 + --> $DIR/check-doc-alias-attr.rs:10:15 | LL | #[doc(alias = "\"")] - | ^^^^^^^^^^^^ + | ^^^^ error: '\n' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:11:7 + --> $DIR/check-doc-alias-attr.rs:11:15 | LL | #[doc(alias = "\n")] - | ^^^^^^^^^^^^ + | ^^^^ error: '\n' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:12:7 + --> $DIR/check-doc-alias-attr.rs:12:15 | LL | #[doc(alias = " - | _______^ + | _______________^ LL | | ")] | |_^ error: '\t' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:14:7 + --> $DIR/check-doc-alias-attr.rs:14:15 | LL | #[doc(alias = "\t")] - | ^^^^^^^^^^^^ + | ^^^^ error: `#[doc(alias = "...")]` cannot start or end with ' ' - --> $DIR/check-doc-alias-attr.rs:15:7 + --> $DIR/check-doc-alias-attr.rs:15:15 | LL | #[doc(alias = " hello")] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: `#[doc(alias = "...")]` cannot start or end with ' ' - --> $DIR/check-doc-alias-attr.rs:16:7 + --> $DIR/check-doc-alias-attr.rs:16:15 | LL | #[doc(alias = "hello ")] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: aborting due to 9 previous errors diff --git a/src/test/ui/doc-alias-crate-level.stderr b/src/test/ui/doc-alias-crate-level.stderr index 45756d6a04bd0..32b42cf9be766 100644 --- a/src/test/ui/doc-alias-crate-level.stderr +++ b/src/test/ui/doc-alias-crate-level.stderr @@ -1,8 +1,8 @@ error: '\'' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/doc-alias-crate-level.rs:7:8 + --> $DIR/doc-alias-crate-level.rs:7:16 | LL | #![doc(alias = "shouldn't work!")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ error: aborting due to previous error From a2d1254e22c37b359a8b89e13a5dd288cc69a268 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 1 Dec 2020 17:32:14 +0100 Subject: [PATCH 3/3] Add documentation for name_value_literal_span methods --- compiler/rustc_ast/src/attr/mod.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 22539bb1d9d19..19c7c479f0429 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -180,6 +180,13 @@ impl Attribute { self.value_str().is_some() } + /// This is used in case you want the value span instead of the whole attribute. Example: + /// + /// ```text + /// #[doc(alias = "foo")] + /// ``` + /// + /// In here, it'll return a span for `"foo"`. pub fn name_value_literal_span(&self) -> Option { match self.kind { AttrKind::Normal(ref item, _) => { @@ -241,6 +248,13 @@ impl MetaItem { self.value_str().is_some() } + /// This is used in case you want the value span instead of the whole attribute. Example: + /// + /// ```text + /// #[doc(alias = "foo")] + /// ``` + /// + /// In here, it'll return a span for `"foo"`. pub fn name_value_literal_span(&self) -> Option { Some(self.name_value_literal()?.span) }