Here is part of my real code (actually example code of the documentation I'm working on). But this might actually be more confusing, and I don't need help in fixing the particular code yet. But since you asked, here it is:
use std::rc::Rc;
use std::cell::RefCell;
use my_sandboxing_system::prelude::*;
use my_sandboxing_system::{Callback, Compile, Machine};
fn collect_output<'a, 'b, M, C>(
machine: &'b M,
setup: C,
run: C,
) -> Result<String, MachineError>
where
M: Machine<'a> + Compile<'a, C> + Callback<'a>,
for<'c> <M as Machine<'a>>::Datum<'b, 'c>: MaybeString<'c>,
// I want to avoid this:
for<'c, 'd> &'d <M as Machine<'a>>::Datum<'b, 'c>: TryInto<&'d str, Error = MachineError>,
{
let output_cell = RefCell::new(String::new());
let output_rc = Rc::new(output_cell);
let output_weak = Rc::downgrade(&output_rc);
let my_print = machine
.callback_1arg(move |s| {
output_weak
.upgrade()
.ok_or("expired")?
.borrow_mut()
// but use `try_into`,
// as I think that's most idiomatic, isn't it?
.push_str((&s).try_into()?);
Ok(vec![])
})?;
machine.compile(None, setup)?.call([my_print])?;
machine.compile(None, run)?.call([])?;
Ok(Rc::try_unwrap(output_rc).unwrap().into_inner())
}
Also note my Problem with HRTBs and associated type bounds in that matter.
I feel like I should remember the wisdom I found once.
Thank you a lot for showing me that workaround, I'll consider using that, but I'm currently tempted to simply do the following:
/// Types that can be an UTF-8 text string
pub trait MaybeString<'c>
where
Self: From<String>,
Self: From<&'c str>,
Self: TryInto<String, Error = DatumConversionError<Self>>,
{
/// Try to interpret datum as Unicode string
fn try_as_str(&self) -> Result<&str, DatumViewError>;
}
Using TryInto
here, because of what @kpreid said here:
And I plan to not use for<'d> &'d Self: TryInto<&'d str, Error = DatumViewError>
either, due to the error I described here:
P.S.: In either case, there must be a compiler bug. Those hints aren't right!