Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Outer attribute after inner attribute error should give more information #61218

Closed
estebank opened this issue May 26, 2019 · 4 comments · Fixed by #63038
Closed

Outer attribute after inner attribute error should give more information #61218

estebank opened this issue May 26, 2019 · 4 comments · Fixed by #63038
Labels
A-diagnostics Area: Messages for errors, warnings, and lints E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. P-low Low priority

Comments

@estebank
Copy link
Contributor

Given the following

#[feature(lang_items)]
#![recursion_limit="100"] //~ ERROR an inner attribute is not permitted following an outer attribute
fn main() {}

we currently emit

error: an inner attribute is not permitted following an outer attribute
--> $DIR/inner-attr.rs:3:3
|
LL | #![recursion_limit="100"]
| ^
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.

We should emit at least the following

error: an inner attribute is not permitted following an outer attribute
  --> $DIR/inner-attr.rs:3:3
   |
LL | #[feature(lang_items)]
   | ---------------------- previous outer attribute
LL | 
LL | #![recursion_limit="100"]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^ not permited following an outer attibute
   |
   = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.

We might also want to provide suggestions when it makes sense (like turning the feature attr into an outer attr).

@estebank estebank added A-diagnostics Area: Messages for errors, warnings, and lints E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. P-low Low priority labels May 26, 2019
@robinboehm
Copy link

Hey @estebank ,

I tried to solve this with a little help of @badboy on a rust meetup.
I wasn't able to run cargo test because of the following message.

rust git:(master) ✗ RUST_BACKTRACE=1 cargo test src/test/ui/parser
   Compiling rustc_codegen_llvm v0.0.0 (/Users/robinboehm/development/rust/rust/src/librustc_codegen_llvm)
   Compiling libc v0.2.54
   Compiling compiler_builtins v0.1.15
   Compiling profiler_builtins v0.0.0 (/Users/robinboehm/development/rust/rust/src/libprofiler_builtins)
   Compiling strip-ansi-escapes v0.1.0
error: failed to run custom build command for `profiler_builtins v0.0.0 (/Users/robinboehm/development/rust/rust/src/libprofiler_builtins)`

Caused by:
  process didn't exit successfully: `/Users/robinboehm/development/rust/rust/target/debug/build/profiler_builtins-48a5ce79ce969ba5/build-script-build` (exit code: 101)
--- stderr
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:347:21
stack backtrace:
   0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   4: <unknown>
   5: <unknown>
   6: <unknown>
   7: <unknown>
   8: <unknown>
   9: <unknown>
  10: <unknown>
  11: <unknown>
  12: <unknown>
  13: <unknown>
  14: <unknown>

warning: build failed, waiting for other jobs to finish...
error: build failed

But I started to add some code you can read here: robinboehm@d71319c

is this going into the right direction?

@estebank
Copy link
Contributor Author

@robinboehm thank you for taking a look at this!

You should be able to run the tests with ./x.py test src/test/ui --stage 1. Use ./x.py test src/test/ui --stage 1 --bless to update the relevant .stderr files.


The code you've written would generate the following output:

note: previous outer attribute
   |
LL | #![recursion_limit="100"]
   | ^

error: an inner attribute is not permitted following an outer attribute
  --> $DIR/inner-attr.rs:3:3
   |
LL | #![recursion_limit="100"]
   |  ^
   |
   = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.

Instead, we'd want this to be a single error. What you'd want to do is 1) get the span for the prior attribute from attrs.last() 2) expand InnerAttributeParsePolicy::NotPermitted to also hold an extra field (Span, &str) and 3) change the following

if let InnerAttributeParsePolicy::NotPermitted { reason } = inner_parse_policy
{
let span = self.span;
self.diagnostic()
.struct_span_err(span, reason)
.note("inner attributes, like `#![no_std]`, annotate the item \
enclosing them, and are usually found at the beginning of \
source files. Outer attributes, like `#[test]`, annotate the \
item following them.")
.emit()
}

to be

                        self.diagnostic()
                            .struct_span_err(span, reason)
                            .span_label(prev_attr_sp, prev_attr_msg)
                            .note("inner attributes, like `#![no_std]`, annotate the item \
                                   enclosing them, and are usually found at the beginning of \
                                   source files. Outer attributes, like `#[test]`, annotate the \
                                   item following them.")
                            .emit()

This lets you point at the prior span in the same error.

The second part of this ticket is changing the linked code to no longer use self.prev_span, but rather synthesize a new span from the first #'s span to the closing ]. You can use beginning_span.to(end_span) to do so. Finally, we change the above to be something like

                        self.diagnostic()
                            .struct_span_err(span, reason)
                            .span_label(span, reason)
                            .span_label(prev_attr_sp, prev_attr_msg)
                            .note("inner attributes, like `#![no_std]`, annotate the item \
                                   enclosing them, and are usually found at the beginning of \
                                   source files. Outer attributes, like `#[test]`, annotate the \
                                   item following them.")
                            .emit()```

@YairHalberstadt
Copy link

@robinboehm

Are you still working on this?

I'm thinking of giving it a try.

@robinboehm
Copy link

robinboehm commented Jun 6, 2019 via email

Centril added a commit to Centril/rust that referenced this issue Jul 28, 2019
Make more informative error on outer attribute after inner

Fixes rust-lang#61218.

?r @estebank
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. P-low Low priority
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants