this attribute sets the base line number for the annotated item, module, or expression.
example:
#[line = 20]
fn main() {
println!("{}", line!()); // prints 21
}
the primary use case is to annotate doctests to use their proper line numbers.
this attribute sets the base line number for the annotated item, module, or expression.
example:
#[line = 20]
fn main() {
println!("{}", line!()); // prints 21
}
the primary use case is to annotate doctests to use their proper line numbers.
An alternative would for rustdoc tests to use their proper line number without needing a new attribute.
through what mechanism would they do that? i was under the impression that rustdoc turns doctests into valid rust programs through simple text preprocessing.
It could be a purely internal attribute, #[rustc_line]
or something. Rustdoc is tightly bound to rustc.
that's still a new attribute. i don't see the advantage of making it perma-unstable when this is something that could be useful for any generated code.
The primary advantage is avoiding 6 months of bikeshed, if it’s not intended for stabilization it can just be implemented with whatever semantics are most useful for rustdoc.
We've had requests for this for a while, and we'd generally like to see it happen. The previous round: pre-RFC: Enable setting of source file, line & column - #8 by CAD97
As evidenced by that discussion, this is endlessly bikesheddable.
Summary:
diagnostic::
)?Personally, based on the above-linked thread, I'm tempted by the idea of feeding a source map into the compiler and having this be entirely outside the scope of the text of a Rust source file.
why not both, through a generalized system of allowing attributes to be specified in an external file like i previously proposed.
line!()
affects the runtime semantics.
i would think that's would fall under the category of reflection, otherwise wouldn't rustfmt be unable to change macro arguments because stringify!()
exists?
stringify!()
is already allowed to differ between rustc versions.
In my experience programs that generate source code are much easier to write if they only have to emit one file. So I prefer the idea of "something that appears in a Rust source file".
My gut says attributes would fit the grain of the language better, but a restriction to items might be a serious problem for programs like yacc
that switch between synthetic code and user supplied code inside an expression.
I absolutely agree that it's easier for (most) code generators. If we want to do the simplest thing for code generators, it should be a macro in the source code.
The advantage of source maps would be to keep the generated code easier to read because it doesn't have those directives everywhere, for cases where there's value in a human reading it, and to have the source maps be easily read and generated by a variety of established tools. (I started to add another point here, that source maps avoid having to define interactions between a macro and other parts of the language, such as passing a macro-generated argument as a filename, but we could always just prohibit that if we wan to keep the macro simpler for the parser, and require that the arguments be literal strings/integers rather than invocations of anything else.)
That said, those tradeoffs may not be important enough to outweigh the ease of code generation. We could potentially have tools that strip out those directives, or translate between them and source maps. Or, it might make sense to support both: have the attribute for the simple case, have the source map for more complex cases.
I agree; I think it's entirely likely that if we embed something in the source file, it will need to be a macro that can appear anywhere.
And for convenience, the macro should have a simple invocation for "reset to current file/line/column", for cases where the generated code switches between code that came from the user and code that's entirely generated (so the only useful source is the generated one).
I would prefer sourcemaps as the ultimate solution, but that may be a long way off. #[line]
seems like a simple addition, so it could be added even if sourcemaps were planned to be added later.
Sourcemaps could be precise enough to specify not just lines, but to map variables from source to the generated code, so they could work in debuggers, and maybe even rust-analyzer.
However, sourcemaps are complicated to generate. This complexity may make them slow to compile or slow to run at build time, so build-time tools could choose not to support source maps anyway. Rust/Cargo may first need to have better caching or distribute pre-built proc macros to enable people to use more complex build-time libraries.
the alternative is making it depend on expression attributes, blocking one nightly feature on another.
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.