impl Field<'_> { fn validate(&self) -> Result<()> { iflet Some(unexpected_display_attr) = iflet Some(display) = &self.attrs.display {
Some(display.original)
} elseiflet Some(fmt) = &self.attrs.fmt {
Some(fmt.original)
} else {
None
} { return Err(Error::new_spanned(
unexpected_display_attr, "not expected here; the #[error(...)] attribute belongs on top of a struct or an enum variant",
));
}
Ok(())
}
}
fn check_non_field_attrs(attrs: &Attrs) -> Result<()> { iflet Some(from) = &attrs.from { return Err(Error::new_spanned(
from.original, "not expected here; the #[from] attribute belongs on a specific field",
));
} iflet Some(source) = &attrs.source { return Err(Error::new_spanned(
source.original, "not expected here; the #[source] attribute belongs on a specific field",
));
} iflet Some(backtrace) = &attrs.backtrace { return Err(Error::new_spanned(
backtrace, "not expected here; the #[backtrace] attribute belongs on a specific field",
));
} if attrs.transparent.is_some() { iflet Some(display) = &attrs.display { return Err(Error::new_spanned(
display.original, "cannot have both #[error(transparent)] and a display attribute",
));
} iflet Some(fmt) = &attrs.fmt { return Err(Error::new_spanned(
fmt.original, "cannot have both #[error(transparent)] and #[error(fmt = ...)]",
));
}
} elseiflet (Some(display), Some(_)) = (&attrs.display, &attrs.fmt) { return Err(Error::new_spanned(
display.original, "cannot have both #[error(fmt = ...)] and a format arguments attribute",
));
}
Ok(())
}
fn check_field_attrs(fields: &[Field]) -> Result<()> { letmut from_field = None; letmut source_field = None; letmut backtrace_field = None; letmut has_backtrace = false; for field in fields { iflet Some(from) = field.attrs.from { if from_field.is_some() { return Err(Error::new_spanned(
from.original, "duplicate #[from] attribute",
));
}
from_field = Some(field);
} iflet Some(source) = field.attrs.source { if source_field.is_some() { return Err(Error::new_spanned(
source.original, "duplicate #[source] attribute",
));
}
source_field = Some(field);
} iflet Some(backtrace) = field.attrs.backtrace { if backtrace_field.is_some() { return Err(Error::new_spanned(
backtrace, "duplicate #[backtrace] attribute",
));
}
backtrace_field = Some(field);
has_backtrace = true;
} iflet Some(transparent) = field.attrs.transparent { return Err(Error::new_spanned(
transparent.original, "#[error(transparent)] needs to go outside the enum or struct, not on an individual field",
));
}
has_backtrace |= field.is_backtrace();
} iflet (Some(from_field), Some(source_field)) = (from_field, source_field) { if from_field.member != source_field.member { return Err(Error::new_spanned(
from_field.attrs.from.unwrap().original, "#[from] is only supported on the source field, not any other field",
));
}
} iflet Some(from_field) = from_field { let max_expected_fields = match backtrace_field {
Some(backtrace_field) => 1 + (from_field.member != backtrace_field.member) as usize,
None => 1 + has_backtrace as usize,
}; if fields.len() > max_expected_fields { return Err(Error::new_spanned(
from_field.attrs.from.unwrap().original, "deriving From requires no fields other than source and backtrace",
));
}
} iflet Some(source_field) = source_field.or(from_field) { if contains_non_static_lifetime(source_field.ty) { return Err(Error::new_spanned(
&source_field.original.ty, "non-static lifetimes are not allowed in the source of an error, because std::error::Error requires the source is dyn Error + 'static",
));
}
}
Ok(())
}
fn contains_non_static_lifetime(ty: &Type) -> bool { match ty { Type::Path(ty) => { let bracketed = match &ty.path.segments.last().unwrap().arguments {
PathArguments::AngleBracketed(bracketed) => bracketed,
_ => returnfalse,
}; for arg in &bracketed.args { match arg {
GenericArgument::Type(ty) if contains_non_static_lifetime(ty) => returntrue,
GenericArgument::Lifetime(lifetime) if lifetime.ident != "static" => { returntrue
}
_ => {}
}
} false
} Type::Reference(ty) => ty
.lifetime
.as_ref()
.map_or(false, |lifetime| lifetime.ident != "static"),
_ => false, // maybe implement later if there are common other cases
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-19)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.