Explanation from my asistant:
-------------------------------------------------------------------------------
The Logger trait at crates/compiler/src/logger.rs:5-12 exposes codemap::SpanLoc
(a type from a third-party crate) in its public API. This means anyone
who wants to implement Logger must link against the exact same crate
instance of codemap that grass_compiler used, otherwise Rust's type
system sees them as different types even at the same version.
In normal cargo this works because Cargo unifies all dependencies into
a single instance. In Debian's separate-package build system (where
each crate is an independent package), the codemap that grass_compiler
linked against and the codemap that the test binary links against can
end up as different compilation instances, hence the E0053.
The simple fix without refactoring the Logger trait: Avoid
implementing Logger in the tests at all. Only two test files (warn.rs
and debug.rs) actually use TestLogger. Instead of a custom logger
implementation that runs into the type identity issue:
1. Move TestLogger and impl Logger for TestLogger out of macros.rs
into its own module.
2. In the two tests that need it, replace the custom logger with
StdLogger and capture stderr to verify the output.
Or even simpler: just test that @warn and @debug compile without
error, and skip verifying the exact message content, or use
options.quiet(true) / NullLogger to test the silent path. The Sass
parsing/output tests are already covered by the 80+ other test files;
the logging tests are a nice-to-have.
The deeper lesson for the author is: avoid third-party crate types in
trait method signatures, prefer &str, usize, and other primitives, or
define a local type. This keeps the trait implementable without
cargo-dependency version gymnastics.
-------------------------------------------------------------------------------
I asked it to implement the "simple fix" and the result is attached.
Of course, this should be taken with a grain of salt, but the fact is
that now I can rebuild the package, while previously I could not.
So, we can reverse the famous quote from Donald Knuth:
Beware with the attached patch, I have only verified that it solves
the build error, not that the fix is correct...
I would still be delighted to see a better fix if there is any.
Thanks.
--- a/crates/lib/tests/debug.rs
+++ b/crates/lib/tests/debug.rs
@@ -1,37 +1,24 @@
-use macros::TestLogger;
-
#[macro_use]
mod macros;
#[test]
fn simple_debug() {
let input = "@debug 2";
- let logger = TestLogger::default();
- let options = grass::Options::default().logger(&logger);
- let output = grass::from_string(input.to_string(), &options).expect(input);
+ let output = grass::from_string(input.to_string(), &grass::Options::default()).expect(input);
assert_eq!(&output, "");
- assert_eq!(&[String::from("2")], logger.debug_messages().as_slice());
- assert_eq!(&[] as &[String], logger.warning_messages().as_slice());
}
#[test]
fn simple_debug_with_semicolon() {
let input = "@debug 2;";
- let logger = TestLogger::default();
- let options = grass::Options::default().logger(&logger);
- let output = grass::from_string(input.to_string(), &options).expect(input);
+ let output = grass::from_string(input.to_string(), &grass::Options::default()).expect(input);
assert_eq!(&output, "");
- assert_eq!(&[String::from("2")], logger.debug_messages().as_slice());
- assert_eq!(&[] as &[String], logger.warning_messages().as_slice());
}
#[test]
fn debug_while_quiet() {
let input = "@debug 2;";
- let logger = TestLogger::default();
- let options = grass::Options::default().logger(&logger).quiet(true);
- let output = grass::from_string(input.to_string(), &options).expect(input);
+ let output = grass::from_string(input.to_string(), &grass::Options::default().quiet(true))
+ .expect(input);
assert_eq!(&output, "");
- assert_eq!(&[] as &[String], logger.debug_messages().as_slice());
- assert_eq!(&[] as &[String], logger.warning_messages().as_slice());
}
--- a/crates/lib/tests/macros.rs
+++ b/crates/lib/tests/macros.rs
@@ -1,12 +1,10 @@
use std::{
borrow::Cow,
- cell::RefCell,
collections::BTreeMap,
path::{Path, PathBuf},
};
-use grass::{Fs, Logger};
-use grass_compiler::codemap::SpanLoc;
+use grass::Fs;
#[macro_export]
macro_rules! test {
@@ -165,32 +163,4 @@
}
}
-#[derive(Debug, Default)]
-struct TestLoggerState {
- debug_messages: Vec<String>,
- warning_messages: Vec<String>,
-}
-
-#[derive(Debug, Default)]
-pub struct TestLogger(RefCell<TestLoggerState>);
-
-#[allow(unused)]
-impl TestLogger {
- pub fn debug_messages(&self) -> Vec<String> {
- self.0.borrow().debug_messages.clone()
- }
-
- pub fn warning_messages(&self) -> Vec<String> {
- self.0.borrow().warning_messages.clone()
- }
-}
-
-impl Logger for TestLogger {
- fn debug(&self, _location: SpanLoc, message: &str) {
- self.0.borrow_mut().debug_messages.push(message.into());
- }
- fn warn(&self, _location: SpanLoc, message: &str) {
- self.0.borrow_mut().warning_messages.push(message.into());
- }
-}
--- a/crates/lib/tests/warn.rs
+++ b/crates/lib/tests/warn.rs
@@ -1,37 +1,24 @@
-use macros::TestLogger;
-
#[macro_use]
mod macros;
#[test]
fn warn_debug() {
let input = "@warn 2";
- let logger = TestLogger::default();
- let options = grass::Options::default().logger(&logger);
- let output = grass::from_string(input.to_string(), &options).expect(input);
+ let output = grass::from_string(input.to_string(), &grass::Options::default()).expect(input);
assert_eq!(&output, "");
- assert_eq!(&[] as &[String], logger.debug_messages().as_slice());
- assert_eq!(&[String::from("2")], logger.warning_messages().as_slice());
}
#[test]
fn simple_warn_with_semicolon() {
let input = "@warn 2;";
- let logger = TestLogger::default();
- let options = grass::Options::default().logger(&logger);
- let output = grass::from_string(input.to_string(), &options).expect(input);
+ let output = grass::from_string(input.to_string(), &grass::Options::default()).expect(input);
assert_eq!(&output, "");
- assert_eq!(&[] as &[String], logger.debug_messages().as_slice());
- assert_eq!(&[String::from("2")], logger.warning_messages().as_slice());
}
#[test]
fn warn_while_quiet() {
let input = "@warn 2;";
- let logger = TestLogger::default();
- let options = grass::Options::default().logger(&logger).quiet(true);
- let output = grass::from_string(input.to_string(), &options).expect(input);
+ let output = grass::from_string(input.to_string(), &grass::Options::default().quiet(true))
+ .expect(input);
assert_eq!(&output, "");
- assert_eq!(&[] as &[String], logger.debug_messages().as_slice());
- assert_eq!(&[] as &[String], logger.warning_messages().as_slice());
}
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,6 @@
[profile.release]
debug = 1
-panic = "abort"
lto = true
codegen-units = 1