Add runtime check to avoid overwrite arg easily in diag and store and restore snapshot when set subdiag arg
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
This commit is contained in:
@@ -289,6 +289,9 @@ pub struct DiagInner {
|
||||
pub suggestions: Suggestions,
|
||||
pub args: DiagArgMap,
|
||||
|
||||
// This is used to store args and restore them after a subdiagnostic is rendered.
|
||||
pub reserved_args: DiagArgMap,
|
||||
|
||||
/// This is not used for highlighting or rendering any error message. Rather, it can be used
|
||||
/// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
|
||||
/// `span` if there is one. Otherwise, it is `DUMMY_SP`.
|
||||
@@ -319,6 +322,7 @@ impl DiagInner {
|
||||
children: vec![],
|
||||
suggestions: Suggestions::Enabled(vec![]),
|
||||
args: Default::default(),
|
||||
reserved_args: Default::default(),
|
||||
sort_span: DUMMY_SP,
|
||||
is_lint: None,
|
||||
long_ty_path: None,
|
||||
@@ -390,7 +394,27 @@ impl DiagInner {
|
||||
}
|
||||
|
||||
pub(crate) fn arg(&mut self, name: impl Into<DiagArgName>, arg: impl IntoDiagArg) {
|
||||
self.args.insert(name.into(), arg.into_diag_arg(&mut self.long_ty_path));
|
||||
let name = name.into();
|
||||
let value = arg.into_diag_arg(&mut self.long_ty_path);
|
||||
// This assertion is to avoid subdiagnostics overwriting an existing diagnostic arg.
|
||||
debug_assert!(
|
||||
!self.args.contains_key(&name) || self.args.get(&name) == Some(&value),
|
||||
"arg {} already exists",
|
||||
name
|
||||
);
|
||||
self.args.insert(name, value);
|
||||
}
|
||||
|
||||
pub fn remove_arg(&mut self, name: &str) {
|
||||
self.args.swap_remove(name);
|
||||
}
|
||||
|
||||
pub fn store_args(&mut self) {
|
||||
self.reserved_args = self.args.clone();
|
||||
}
|
||||
|
||||
pub fn restore_args(&mut self) {
|
||||
self.args = std::mem::take(&mut self.reserved_args);
|
||||
}
|
||||
|
||||
/// Fields used for Hash, and PartialEq trait.
|
||||
@@ -1423,6 +1447,12 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||
self.downgrade_to_delayed_bug();
|
||||
self.emit()
|
||||
}
|
||||
|
||||
pub fn remove_arg(&mut self, name: &str) {
|
||||
if let Some(diag) = self.diag.as_mut() {
|
||||
diag.remove_arg(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Destructor bomb: every `Diag` must be consumed (emitted, cancelled, etc.)
|
||||
|
||||
Reference in New Issue
Block a user