Skip to content
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

Selector Widget error #20

Open
giannissc opened this issue Jan 27, 2021 · 19 comments
Open

Selector Widget error #20

giannissc opened this issue Jan 27, 2021 · 19 comments
Labels
question Further information is requested

Comments

@giannissc
Copy link
Contributor

the trait bound `Destination: druid::data::Data` is not satisfied
  --> src\main.rs:45:46
   |
45 |           Scroll::new(ListSelect::build_widget(vec![
   |  ______________________________________________^
46 | |             ("to Sydney", Destination::Sydney),
47 | |             ("to Petaluma", Destination::Petaluma),
48 | |             ("to Tokyo", Destination::Tokyo),
49 | |             ("to Paris", Destination::Paris),
50 | |         ]))
   | |_________^ the trait `druid::data::Data` is not implemented for `Destination`
@giannissc
Copy link
Contributor Author

This happens when extracting example and running it as an isolated instance @maan2003

@richard-uk1
Copy link
Collaborator

Have you tried deriving Data for your type?

@giannissc
Copy link
Contributor Author

I have done so but when it didn't work I copied the example from nursury and it didn't work either.

dropdown_test.zip

@richard-uk1
Copy link
Collaborator

Try replacing vec![..] with Arc::new(vec![..]). Data::same needs to run quickly, and so isn't implemented for Vec<_>, only for Arc<Vec<_>>

@giannissc
Copy link
Contributor Author

Is it compatible with the im crate as well?

@richard-uk1
Copy link
Collaborator

richard-uk1 commented Jan 27, 2021

So because im::Vector is immutable, using b-trees internally, it is as cheap to compare as Arc (a pointer equality check). So Data is implemented for im types.

Rather than import the im crate directly, it's best to turn on the im feature of druid and use the types that way, to ensure the version of im that has the traits implemented is the same as the one you're using. Version conflicts when using traits can lead to very confusing error messages.

@richard-uk1 richard-uk1 added the question Further information is requested label Jan 27, 2021
@giannissc
Copy link
Contributor Author

Well I used vector but I am getting the following errors

error[E0277]: the trait bound `Destination: druid::data::Data` is not satisfied
  --> src\main.rs:46:37
   |
46 |           Scroll::new(ListSelect::new(vector![
   |  _____________________________________^
47 | |             ("to Sydney", Destination::Sydney),
48 | |             ("to Petaluma", Destination::Petaluma),
49 | |             ("to Tokyo", Destination::Tokyo),
50 | |             ("to Paris", Destination::Paris),
51 | |         ]))
   | |_________^ the trait `druid::data::Data` is not implemented for `Destination`
   | 
  ::: C:\Users\John\.cargo\git\checkouts\druid-widget-nursery-63e9f3f67c4f288a\5e4a8d7\src\list_select.rs:36:48
   |
36 |           values: impl IntoIterator<Item = (impl Into<LabelText<T>> + 'static, T)>,
   |                                                  ------------------ required by this bound in `ListSelect::<T>::new`
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `impl druid::widget::widget::Widget<Destination>: druid::Widget<_>` is not satisfied
  --> src\main.rs:46:21
   |
46 |           Scroll::new(ListSelect::new(vector![
   |  _____________________^
47 | |             ("to Sydney", Destination::Sydney),
48 | |             ("to Petaluma", Destination::Petaluma),
49 | |             ("to Tokyo", Destination::Tokyo),
50 | |             ("to Paris", Destination::Paris),
51 | |         ]))
   | |__________^ the trait `druid::Widget<_>` is not implemented for `impl druid::widget::widget::Widget<Destination>`
   |
   = note: required by `Scroll::<T, W>::new`

error[E0599]: no method named `vertical` found for struct `Scroll<_, impl druid::widget::widget::Widget<Destination>>` in the current scope
  --> src\main.rs:52:10
   |
52 |         .vertical()
   |          ^^^^^^^^ method not found in `Scroll<_, impl druid::widget::widget::Widget<Destination>>`
   |
   = note: the method `vertical` exists but the following trait bounds were not satisfied:
           `impl druid::widget::widget::Widget<Destination>: druid::Widget<_>`

error[E0277]: the trait bound `Transportation: druid::data::Data` is not satisfied
  --> src\main.rs:58:29
   |
58 |           DropdownSelect::new(vector![
   |  _____________________________^
59 | |             ("by car", Transportation::Car),
60 | |             ("by train", Transportation::Train),
61 | |             ("by plane", Transportation::Plane),
62 | |             ("in a yellow submarine", Transportation::Submarine),
63 | |         ])
   | |_________^ the trait `druid::data::Data` is not implemented for `Transportation`
   | 
  ::: C:\Users\John\.cargo\git\checkouts\druid-widget-nursery-63e9f3f67c4f288a\5e4a8d7\src\dropdown_select.rs:43:48
   |
43 |           values: impl IntoIterator<Item = (impl Into<LabelText<T>> + 'static, T)> + Clone + 'static,
   |                                                  ------------------ required by this bound in `DropdownSelect::<T>::new`
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0599]: no method named `align_left` found for opaque type `impl druid::widget::widget::Widget<Transportation>` in the current scope
  --> src\main.rs:64:10
   |
64 |         .align_left()
   |          ^^^^^^^^^^ method not found in `impl druid::widget::widget::Widget<Transportation>`
   |
   = note: the method `align_left` exists but the following trait bounds were not satisfied:
           `impl druid::widget::widget::Widget<Transportation>: druid::Widget<_>`
           which is required by `impl druid::widget::widget::Widget<Transportation>: WidgetExt<_>`
           `&impl druid::widget::widget::Widget<Transportation>: druid::Widget<_>`
           which is required by `&impl druid::widget::widget::Widget<Transportation>: WidgetExt<_>`
           `&mut impl druid::widget::widget::Widget<Transportation>: druid::Widget<_>`
           which is required by `&mut impl druid::widget::widget::Widget<Transportation>: WidgetExt<_>`
   = help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
   |
15 | use druid::widget::widget_ext::WidgetExt;
   |

error: aborting due to 5 previous errors; 1 warning emitted

Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `dropdown_test`

@giannissc
Copy link
Contributor Author

Can you help me out @derekdreery ?

@richard-uk1
Copy link
Collaborator

So your error messages mention that the trait Data is not implemented for your data types. Any data types that you use in druid need to have Data implemented for them. Fortunately you can just do use druid::Data and then #[derive(Data)] on your data types to get the impl.

The last error is there because you haven't done use druid::WidgetExt when you need to for the function you use.

@giannissc
Copy link
Contributor Author

But already have all that. This is a copy from the example of the widget

@giannissc
Copy link
Contributor Author

Here is the code:

// Copyright 2019 The Druid Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use druid::widget::{CrossAxisAlignment, Flex, Label, Scroll};
use druid::{AppLauncher, Data, Env, Insets, Lens, Widget, WidgetExt, WindowDesc};
use druid_widget_nursery::{DropdownSelect, ListSelect};
use druid::im::{vector};

#[derive(Clone, Copy, Data, Debug, PartialEq)]
enum Destination {
    Sydney,
    Petaluma,
    Tokyo,
    Paris,
}

//#[derive(Clone, Copy, Data, Debug, PartialEq)]
#[derive(Data, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
enum Transportation {
    Car,
    Train,
    Plane,
    Submarine,
}

#[derive(Data, Clone, Lens)]
struct AppData {
    destination: Destination,
    transportation: Transportation,
}

fn main_widget() -> impl Widget<AppData> {
    let mut row = Flex::row().cross_axis_alignment(CrossAxisAlignment::Start);
    row.add_flex_child(
        Scroll::new(ListSelect::new(vector![
            ("to Sydney", Destination::Sydney),
            ("to Petaluma", Destination::Petaluma),
            ("to Tokyo", Destination::Tokyo),
            ("to Paris", Destination::Paris),
        ]))
        .vertical()
        .lens(AppData::destination),
        1.0,
    );
    row.add_default_spacer();
    row.add_flex_child(
        DropdownSelect::new(vector![
            ("by car", Transportation::Car),
            ("by train", Transportation::Train),
            ("by plane", Transportation::Plane),
            ("in a yellow submarine", Transportation::Submarine),
        ])
        .align_left()
        .lens(AppData::transportation),
        1.0,
    );

    let mut col = Flex::column().cross_axis_alignment(CrossAxisAlignment::Start);
    col.add_child(
        Label::new(|d: &AppData, _: &Env| {
            format!("Let's go to {:?} by {:?}", d.destination, d.transportation)
        })
        .padding(Insets::uniform_xy(5., 5.)),
    );
    col.add_child(row);
    col
}

fn main() {
    let main_window = WindowDesc::new(main_widget())
        .title("Select")
        .window_size((250., 300.));

    // create the initial app state
    let app_data = AppData {
        transportation: Transportation::Car,
        destination: Destination::Tokyo,
    };

    // start the application
    AppLauncher::with_window(main_window)
        .use_env_tracing()
        .launch(app_data)
        .expect("Failed to launch application");
}

@richard-uk1
Copy link
Collaborator

richard-uk1 commented Mar 7, 2021

Could you post a full version that you expect to work (ideally in a git repository I can clone). Also, you may get quicker (and more varied) answers at https://xi.zulipchat.com/

@giannissc
Copy link
Contributor Author

The repository: https://github.com/giannissc/dropdown-widget-test @derekdreery

@cincodenada
Copy link
Contributor

cincodenada commented Nov 21, 2021

Hello, I came here with the same issue - I tried to use the DropdownSelect, and was met with an example that simply didn't work. The error the trait druid::data::Data is not implemented for Destination is particularly unhelpful, since to a casual observer, it seems to be quite explicitly derived:

#[derive(Clone, Copy, Data, Debug, PartialEq)]
enum Destination {
    Sydney,
    Petaluma,
    Tokyo,
    Paris,
}

So far most errors I've encountered with Rust have pointed me in a useful direction, but this one has me stumped - I have no clue where to even start digging, here, because the error points at a thing that seems to contradict everything I know about traits and derivation.

@giannissc I see you closed this without further comment, did you ever figure anything out here?

@richard-uk1 richard-uk1 reopened this Nov 21, 2021
@richard-uk1
Copy link
Collaborator

richard-uk1 commented Nov 21, 2021

Hey @cincodenada I've re-opened the issue so we can discuss. I agree that the error looks very unhelpful. It's worth mentioning that this library is very much an 'experimental' one (very low barrier to additions), so problems like this are expected. I'm keen to fix problems as they come up, though! :)

Are you saying that you ran one of the examples and it failed to compile? If not, could you post your code somewhere (the code that doesn't work), so I can take a look at it. Or can I just look at the repo that @giannissc posted?

@giannissc I'm sorry I missed your post before where you posted the repo - I must have skipped the notification (very easily done IMO). If you're no longer interested feel free to unsubscribe from the issue.

@jplatte
Copy link
Member

jplatte commented Nov 21, 2021

The repository: giannissc/dropdown-widget-test @derekdreery

I was able to make it work with a simple patch.
diff --git a/Cargo.toml b/Cargo.toml
index 54b665d..ed9e399 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,5 +7,5 @@ edition = "2018"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

 [dependencies]
-druid = { git = "https://github.com/linebender/druid.git", version = "0.7", features = ["im"]}
+druid = { git = "https://github.com/linebender/druid.git", rev = "0a82b127eac325c9c721364a5d81f1bfd931cb13", features = ["im"]}
 druid-widget-nursery = {git = "https://github.com/linebender/druid-widget-nursery.git"}
diff --git a/src/main.rs b/src/main.rs
index 1f78036..4d59a0f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -90,7 +90,6 @@ fn main() {

     // start the application
     AppLauncher::with_window(main_window)
-        .use_env_tracing()
         .launch(app_data)
         .expect("Failed to launch application");
 }

Realistically, you would specify the git rev for both druid and druid-widget-nursery. But the important part is that you depend on druid directly in the same way druid-widget-nursery depends on it (same git repo / branch / rev exactly), otherwise you will pull in two versions of druid and the widgets from the nursery will implement the Data trait of a different druid than the one AppLauncher and such are used from.

You can check with cargo tree -d whether you have duplicate dependencies. Another possibility is running cargo tree -i druid, which will show your direct and indirect dependencies on the package, or raise an error if you have duplicate dependencies on that package specifically.

cincodenada added a commit to cincodenada/druid-widget-nursery that referenced this issue Nov 22, 2021
cincodenada added a commit to cincodenada/druid-widget-nursery that referenced this issue Nov 22, 2021
@cincodenada
Copy link
Contributor

cincodenada commented Nov 22, 2021

Ah, thank you! With two versions of druid in play explains the confounding error message makes a lot more sense, I've run into similar issues in other languages before and should have suspected something like that. I was indeed able to resolve the issue following what you did above, pinning the druid version to match the druid_widget_nursery version.

I expected the nursery to be a little finicky by nature, so I wasn't surprised that I ran into issues, I was just stumped, so thanks! I am still getting to know my way around Rust, especially the packaging intricacies, so I also appreciate the cargo tips!

I've opened #87 to try to make a note of this in the docs as suggested by @maan2003 on Zulip, I think I got the right Cargo.toml setup but please do give it a once-over. Thanks!

For those reading along in the future: there's further discussion of this issue in this Zulip thread, and the discussion around Arcs and vectors above seems to be a red herring in this case, the root issue ended up being the two versions of druid fighting with each other. The bits about vectors and immutability are useful if you're trying to use vectors as Data attributes, but in this case the vectors were just part of the widget's interface, and the data attributes themselves were simple enums.

maan2003 pushed a commit that referenced this issue Nov 22, 2021
This resolves the documentation issue that led to #20
@richard-uk1
Copy link
Collaborator

Hmm, we pinned the druid version to avoid breakage when druid updates, but maybe it actually causes more harm than good. Maybe we should get rid of it, and put a note on the repo that because we track master, things might break. It would probably be less confusing for library users, and would certainly lead to less confusing error messages!

@jplatte
Copy link
Member

jplatte commented Nov 22, 2021

I think pinning is the right thing to do, otherwise it's hard to find out which version to downgrade to if druid-widget-nursery doesn't work the latest druid version.

cincodenada added a commit to cincodenada/circularfft that referenced this issue Nov 29, 2021
Resolved my weird double-version issues that were causing strange
errors, thanks Druid folks!

Hot dang, this is exciting

linebender/druid-widget-nursery#20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants