-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Auto-completion for warp Filters #4774
Comments
Triage: still an issue, a somewhat more direct example use warp::Filter;
fn main() {
warp::path("hello")
.and(warp::path::param())
.and(warp::header("user-agent")) // <- this and doesn't resolve
.map(|param: String, agent: String| format!("Hello {}, whose agent is {}", param, agent));
} |
Note: This is still an issue on HEAD/master (5ca7cd9). |
According to @flodiebold, macro expansions in associated type positions aren't expanded yet: #5455 (comment), which is probably also the cause of this issue (Warp utilizes macros in associated type positions https://github.com/seanmonstar/warp/blob/032123c1b9636f7999d5bc6d9ceda6cd85062f77/src/generic.rs#L119). |
Looks like chalk was unable to solve this Implemented goal:
It's tricky to minimize the example, but from digging through the logs I think the opaque type is from one of these two:
|
@detrumi I've reduce the issue down to this code: pub struct Product<H, T: HList>(H, T);
// Converts Product (and ()) into tuples.
pub trait HList {
type Tuple: Tuple<HList = Self>;
}
// Typeclass that tuples can be converted into a Product (or unit ()).
pub trait Tuple {
type HList: HList<Tuple = Self>;
}
pub type CombinedTuples<T, U> =
<<<T as Tuple>::HList as Combine<<U as Tuple>::HList>>::Output as HList>::Tuple;
// Combines Product together.
pub trait Combine<T: HList> {
type Output: HList;
}
impl<T: HList> Combine<T> for () {
type Output = T;
}
impl<H, T: HList, U: HList> Combine<U> for Product<H, T>
where
T: Combine<U>,
Product<H, <T as Combine<U>>::Output>: HList,
{
type Output = Product<H, <T as Combine<U>>::Output>;
}
impl HList for () {
type Tuple = ();
}
impl Tuple for () {
type HList = ();
}
impl<T16> HList for Product<T16, ()> {
type Tuple = (T16,);
}
impl<T16> Tuple for (T16,) {
type HList = Product<T16, ()>;
}
pub trait FilterBase {
type Extract: Tuple;
}
pub trait Filter: FilterBase {
}
impl<T: FilterBase> Filter for T {}
trait Mumbo {
type Extract;
fn mumbo(&self) -> Self::Extract;
}
impl<T, U> Mumbo for (T, U)
where
// There trait bounds are taken from `And`
T: Filter,
U: Filter,
// When this bound is commented out, the type of `y` will change to an unnormalized type:
// let y: <(Exact<&str>, impl Filter<Extract = (String,)>) as Mumbo>::Extract
<T::Extract as Tuple>::HList: Combine<<U::Extract as Tuple>::HList>,
{
type Extract = CombinedTuples<T::Extract, U::Extract>;
fn mumbo(&self) -> Self::Extract {
unreachable!()
}
}
pub struct Exact<P>(P);
impl<P> FilterBase for Exact<P> {
type Extract = ();
}
struct Param;
impl FilterBase for Param {
type Extract = (String,);
}
// Param as impl Trait
fn impl_param() -> impl Filter<Extract = (String,)> {
Param
}
fn main() {
let a = Exact(""); // Exact<&str>
let b = Param;
let c = impl_param();
let x = (a, b).mumbo(); // (String,)
let y = (a, c).mumbo(); // {unknown} but should be (String,)
} The EDIT: I minimized it further. |
That looks like it requires inference of auto traits for opaque types, which we currently don't do. |
@flodiebold What kind of auto-trait are you talking about? |
You had a |
@flodiebold Ah yes, the updated example doesn’t have that bound anymore so I think there is more to it. |
@flodiebold @detrumi @jackh726? It seems like an issue with chalk: #[test]
fn warp() {
test! {
program {
struct Product<H, T>
where
T: HList
{}
trait HList {
type Tuple: Tuple<HList=Self>;
}
trait Tuple {
type HList: HList<Tuple=Self>;
}
trait Combine<T>
where
T: HList
{
type Output: HList;
}
impl<T> Combine<T> for ()
where
T: HList
{
type Output = T;
}
impl<H, T, U> Combine<U> for Product<H, T>
where
T: HList,
T: Combine<U>,
U: HList,
Product<H, <T as Combine<U>>::Output>: HList,
{
type Output = Product<H, <T as Combine<U>>::Output>;
}
impl HList for () {
type Tuple = ();
}
impl Tuple for () {
type HList = ();
}
impl<T16> HList for Product<T16, ()> {
type Tuple = (T16,);
}
impl<T16> Tuple for (T16,) {
type HList = Product<T16, ()>;
}
trait FilterBase {
type Extract: Tuple;
}
trait Filter
where Self: FilterBase {
}
impl<T> Filter for T
where T: FilterBase {}
trait Mumbo {
type Extract;
}
impl<T, U> Mumbo for (T, U)
where
T: Filter,
U: Filter,
<<T as FilterBase>::Extract as Tuple>::HList: Combine<<<U as FilterBase>::Extract as Tuple>::HList>
{
type Extract = <<<<T as FilterBase>::Extract as Tuple>::HList as Combine<<<U as FilterBase>::Extract as Tuple>::HList>>::Output as HList>::Tuple;
}
struct Exact<T> {}
impl<T> FilterBase for Exact<T> {
type Extract = ();
}
struct Param {}
impl FilterBase for Param {
type Extract = (usize,);
}
opaque type AnonParam: FilterBase<Extract = (usize,)> = Param;
}
goal {
(Exact<usize>, Param): Mumbo
} yields {
"Unique; substitution [], lifetime constraints []"
}
goal {
(Exact<usize>, AnonParam): Mumbo
} yields {
"Unique; substitution [], lifetime constraints []"
}
}
} The first goal succeeds. The second one does not ( |
Hm. You've got your |
@flodiebold You mean something like this: opaque type AnonParam: Filter + FilterBase<Extract = (usize,)> = Param; ? That also gives Besides should it matter? Since this impl exists: impl<T> Filter for T
where T: FilterBase {} |
Probably not, but just making sure. |
I'll open an upstream issue (rust-lang/chalk#700). |
@detrumi can you look into this? Looks like something related to opaque types and I'm not really going to have time to look into it this week. |
That's weird. After #8856 this seems to work. However the chalk test still fails O.o Edit: nvm, it still doesn’t work. |
No auto-completions are shown here (at the current cursor
<|>
).EDIT:
Repro:
Test code
The text was updated successfully, but these errors were encountered: