How can I disable the "unused attribute" warning when using Serde library? - json

In addition to disabling the warning, why does it happen?
use serde_json::from_str;
use serde_json::error::Result;
#[derive(Deserialize)]
pub struct Config {
#[serde(rename="cudaBlasDylibPath")]
pub cuda_blas_dylib_path: String,
}
impl Config {
pub fn new() -> Result<Config> {
from_str("{}")
}
}
src/config.rs:4:10: 4:21 warning: unused attribute, #[warn(unused_attributes)] on by default
src/config.rs:4 #[derive(Deserialize)]
Adding #[allow(unused_attributes)] doesn't help.

Here's the full output from the compiler:
src/main.rs:10:10: 10:21 warning: unused attribute, #[warn(unused_attributes)] on by default
src/main.rs:10 #[derive(Deserialize)]
^~~~~~~~~~~
src/main.rs:10:10: 10:21 note: in this expansion of #[derive_Deserialize] (defined in src/main.rs)
What this means is that the warning is within the code for the impl generated by the #[derive] attribute. However, it's hard to understand what's going on without seeing the code!
Fortunately, we can ask the compiler to show us the generated code. We need to pass additional parameters to rustc, specifically -Z unstable-options --pretty=expanded. If you're using Cargo, delete the compiled crate or run cargo clean (Cargo does nothing if the target is up to date), then run this command:
$ cargo rustc -- -Z unstable-options --pretty=expanded > src/main-expanded.rs
We can then try to compile src/main-expanded.rs with rustc. If you're using Cargo, use the command Cargo prints when you run cargo build --verbose (when the target is not up to date), but replace the name of the root source file with the new file we just generated – or you can just swap your main.rs or lib.rs with the expanded source. It might not always work, but when it does, it can provide some valuable insight.
We now get a clearer picture of the situation:
src/main-expanded.rs:17:5: 17:43 warning: unused attribute, #[warn(unused_attributes)] on by default
src/main-expanded.rs:17 #[serde(rename = "cudaBlasDylibPath")]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main-expanded.rs:20:1: 20:25 warning: unused attribute, #[warn(unused_attributes)] on by default
src/main-expanded.rs:20 #[automatically_derived]
^~~~~~~~~~~~~~~~~~~~~~~~
Here, the warning on the #[serde] attribute is probably caused by the fact that the struct no longer has the #[derive(Deserialize)] attribute, which is what processes the attribute. Also, it's not part of the expansion of the #[derive(Deserialize)] attribute, so that's not the attribute the original warning complained about.
It looks like the #[automatically_derived] attribute is the culprit here. This attribute appears to be used mainly by rustdoc (the documentation generation tool), but it has no meaning when compiling.
The implementation of #[derive] for derivable traits known to rustc emits the attribute like this:
let attr = cx.attribute(
self.span,
cx.meta_word(self.span,
InternedString::new("automatically_derived")));
// Just mark it now since we know that it'll end up used downstream
attr::mark_used(&attr);
My guess is that serde doesn't call the mark_used function, which is what causes the warning. The only occurrences of "automatically_derived" in serde's source code are in invocations of the quote_item! macro, which probably doesn't emit a call to mark_used (and it should probably not do it either).

Related

Why is "Warning: Implicit string type conversion from AnsiString to UnicodeString" here while both are Strings?

Here I get an warning Warning: Implicit string type conversion from "AnsiString" to "UnicodeString"
....
{$mode DelphiUnicode}
{$H+}
....
Function THeader.ToHtml(Constref input: String): String;
Begin
Result := Format('<h%d>%s</h%d>', [FLevel, Chunk(input), FLevel]); // <--- HERE !
End;
My project settings include -MDelphiUnicode. My Lazarus version is 2.2.2.
As I understand it means that if Chunk() returns symbols outside of ASCII (Unicode), then the Result will be problematic. Right? What to do with this warning? Sure, I can cast the Format() result to String. But why is it required? I see that Format's prototype is:
// somewhere in the sysstrh.inc ...
Function Format (Const Fmt : String; const Args : Array of const) : String;
so it already returns a String (which is magically UnicodeString in my case, as I think). What is the problem actually here? And how to work in the correct way with such library functions like Format() (for instance, GetOptionValue() of TCustomApplication)?
ps. I read FreePascal Wiki about Unicode and String types, but I still cannot understand the reason of this warning :)
There are multiple reasons to do so.
The exact codepage of ansistring is under control of the RTL, which can query the OS for it, without the compiler knowing the details. In Lazarus applications this is generally set to utf8, but the compiler doesn't know that.
So calling a ansistring format() could corrupt strings, and repeated conversions are of course also not ideal for a performance.
delphiunicode is a work in progress, and I would not recommend using it (yet) out of habit, only if you really know what you are doing (and by that I mean knowing the state of it in FPC, not that it works in Delphi)
The original plan was to migrate to unicodestring fully, but since Windows now allows UTF8 as native 1-byte codepage (see thick in application tab of project options), the progress on that migration is glacial.
In short, consider arranging your code as much as possible so that string type doesn't matter, and then use utf8 ansistrings in Lazarus for unicode.
Or ignore the warnings, or disable them with some -vn parameter that allows you to disable specific hints/warnings

Warning on prepending variables with $

When I have a selector that I use several times, I like to prepend it with $ So if I'm using $('body') all over my script, I'll make a variable, $body. The warning arises, in this particular case, when I do $anElement.appendTo($body) I get the warning:
Argument type JQuery|jQuery|html element is not assignable to parameter type JQuery|element|string
I was told this is actually pretty common and acceptable practice, so is there a way I can turn this warning off? I couldn't seem to find any particular entry that disabled this in the inspections.
What I'm doing is this:
$('<div>,
{class:"aClass", text: "some text"}
).appendTo($body);
The warning is under Javascript > General > Signature Mismatch.

Equivalent of abbrev-mode but for functions?

I'm a big fan of abbrev-mode and I'd like something a bit similar: you start typing and as soon as you enter some punctation (or just a space would be enough) it invokes a function (if I type space after a special abbreviation, of course, just like abbrev-mode does).
I definitely do NOT want to execute some function every single time I hit space...
So instead of expanding the abbreviation using abbrev-mode, it would run a function of my choice.
Of course it needs to be compatible with abbrev-mode, which I use all the time.
How can I get this behavior?
One approach could be to use pre-abbrev-expand-hook. I don't use abbrev mode myself, but it rather sounds as if you could re-use the abbrev mode machinery this way, and simply define some 'abbreviations' which expand to themselves (or to nothing?), and then you catch them in that hook and take whatever action you wish to.
The expand library is apparently related, and that provides expand-expand-hook, which may be another alternative?
edit: Whoops; pre-abbrev-expand-hook is obsolete since 23.1
abbrev-expand-functions is the correct variable to use:
Wrapper hook around `expand-abbrev'.
The functions on this special hook are called with one argument:
a function that performs the abbrev expansion. It should return
the abbrev symbol if expansion took place.
See M-x find-function RET expand-abbrev RET for the code, and you'll also want to read C-h f with-wrapper-hook RET to understand how this hook is used.
EDIT:
Your revised question adds some key details that my answer didn't address. phils has provided one way to approach this issue. Another would be to use yasnippet . You can include arbitrary lisp code in your snippet templates, so you could do something like this:
# -*- mode: snippet -*-
# name: foobars
# key: fbf
# binding: direct-keybinding
# --
`(foo-bar-for-the-win)`
You'd need to ensure your function didn't return anything, or it would be inserted in the buffer. I don't use abbrev-mode, so I don't know if this would introduce conflicts. yas/snippet takes a bit of experimenting to get it running, but it's pretty handy once you get it set up.
Original answer:
You can bind space to any function you like. You could bind all of the punctuation keys to the same function, or to different functions.
(define-key your-mode-map " " 'your-choice-function)
You probably want to do this within a custom mode map, so you can return to normal behaviour when you switch modes. Globally setting space to anything but self-insert would be unhelpful.
Every abbrev is composed of several elements. Among the main elements are the name (e.g. "fbf"), the expansion (any string you like), and the hook (a function that gets called). In your case it sounds like you want the expansion to be the empty string and simply specify your foo-bar-for-the-win as the hook.

Remove Runtime Checks compiler flag per-project in CMAKE

I have a CMAKE configuration where all my project configurations include the /RTC1 (Both Runtime Checks) compiler flag. However, I wish to switch to the Default option for only one project, as it also has the /clr compiler flag; which is incompatible with the Runtime Checks flag. I'm relatively new to CMAKE, so this may have an obvious solution, but I've so far been unable to find this.
Any help would be appreciated.
I didn't manage to find a solution whereby I could nicely remove the particular options, but I did find a way of stripping the option from the compiler flags variable using a REGEX REPLACE:
STRING (REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
Where this may not be the most ideal approach, it has worked well in my situation where it is a special-cased scenario.
I'd recently faced with the same problem and found no elegant solution. However this code does the job:
foreach(flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
STRING (REGEX REPLACE "/RTC[^ ]*" "" ${flag_var} "${${flag_var}}")
endforeach(flag_var)
set_property(TARGET necessary_targets_here APPEND_STRING PROPERTY COMPILE_FLAGS " /RTC1")
If you only need to clear /RTC flag for one configuration (ex. Debug) you may try the following approach:
STRING (REGEX REPLACE "/RTC[^ ]*" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
foreach(target_var necessary_targets_here)
target_compile_options(${target_var} PRIVATE $<$<CONFIG:Debug>: /RTC1>)
endforeach()
Please, note using generator expression $<$<CONFIG:Debug>: /RTC1 > which expands to /RTC1 only in Debug.
If you are adding your flags with add_definitions(), then you can remove them with remove_definitions, see documentation.
Also, you can play with COMPILE_DEFINITIONS target property.

Should we overload the meaning of configuration settings?

Imagine an instance of some lookup of configuration settings called "configuration", used like this:
if(! string.IsNullOrEmpty(configuration["MySetting"])
{
DoSomethingWithTheValue(configuration["MySetting"]);
}
The meaning of the setting is overloaded. It means both "turn this feature on or off" and "here is a specific value to do something with". These can be decomposed into two settings:
if(configuration["UseMySetting"])
{
DoSomethingWithTheValue(configuration["MySetting"]);
}
The second approach seems to make configuration more complicated, but slightly easier to parse, and it separate out the two sorts of behaviour. The first seems much simpler at first but it's not clear what we choose as the default "turn this off" setting. "" might actually a valid value for MySetting.
Is there a general best practice rule for this?
I find the question to be slightly confusing, because it talks about (1) parsing, and (2) using configuration settings, but the code samples are for only the latter. That confusion means that my answer might be irrelevant to what you intended to ask. Anyway...
I suggest an approach that is illustrated by the following pseudo-code API (comments follow afterwards):
class Configuration
{
void parse(String fileName);
boolean exists(String name);
String lookupString(String name);
String lookupString(String name, String defaultValue);
int lookupInt(String name);
int lookupInt(String name, int defaultValue);
float lookupFloat(String name);
float lookupFloat(String name, float defaultValue);
boolean lookupBoolean(String name);
boolean lookupBoolean(String name, boolean defaultValue);
... // more pairs of lookup<Type>() operations for other types
}
The parse() operation parses a configuration file and stores the parsed data in a convenient format, for example, in a map or hash-table. (If you want, parse() can delegate the parsing to a third-party library, for example, a parser for XML, Java Properties, JSON, .ini files or whatever.)
After parsing is complete, your application can invoke the other operations to retrieve/use the configuration settings.
A lookup<Type>() operation retrieves the value of the specified name and parses it into the specified type (and throws an exception if the parsing fails). There are two overloadings for each lookup<Type>() operation. The version with one parameter throws an exception if the specified variable does not exist. The version with an extra parameter (denoting a default value) returns that default value if the specified variable does not exist.
The exists() operation can be used to test whether a specified name exists in the configuration file.
The above pseudo-code API offers two benefits. First, it provides type-safe access to configuration data (which wasn't a stated requirement in your question, but I think it is important anyway). Second, it enables you to distinguish between "variable is not defined in configuration" and "variable is defined but its value happens to be an empty string".
If you have already committed yourself to a particular configuration syntax, then just implement the above Configuration class as a thin wrapper around a parser for the existing configuration syntax. If you haven't already chosen a configuration syntax and if your project is in C++ or Java, then you might want to look at my Config4* library, which provides a ready-to-use implementation of the above pseudo-code class (with a few extra bells and whistles).