Add no_implicit_prelude to proc macro tests (#2033)

* Add no_implicit_prelude to derive_props test

* Add no_implicit_prelude to html_macro tests

* Fix function_component macro tests

function_component macro tests weren't being run by try build due to
change in dir name. Imports corrected now that function_component is now
in yew.

Adds no_implicit_prelude to *-pass tests

* Add no_implicit_prelude to props_macro tests

* fix typo in comment
This commit is contained in:
mc1098 2021-09-05 23:33:30 +01:00 committed by GitHub
parent df3303f00b
commit 58753d9607
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 400 additions and 355 deletions

View File

@ -5,7 +5,7 @@ use std::cmp::{Ord, Ordering, PartialEq, PartialOrd};
use std::convert::TryFrom;
use syn::parse::Result;
use syn::spanned::Spanned;
use syn::{Error, Expr, Field, Type, TypePath, Visibility};
use syn::{Error, Expr, Field, Path, Type, TypePath, Visibility};
#[allow(clippy::large_enum_variant)]
#[derive(PartialEq, Eq)]
@ -167,7 +167,7 @@ impl PropField {
} else if matches!(
&named_field.ty,
Type::Path(TypePath { path, .. })
if path.segments.len() == 1 && path.segments[0].ident == "Option"
if is_path_an_option(path)
) {
Ok(PropAttr::Option)
} else {
@ -178,6 +178,36 @@ impl PropField {
}
}
fn is_path_segments_an_option(path_segments: impl Iterator<Item = String>) -> bool {
fn is_option_path_seg(seg_index: usize, path: &str) -> u8 {
match (seg_index, path) {
(0, "core") => 0b001,
(0, "std") => 0b001,
(0, "Option") => 0b111,
(1, "option") => 0b010,
(2, "Option") => 0b100,
_ => 0,
}
}
path_segments
.enumerate()
.fold(0, |flags, (i, ps)| flags | is_option_path_seg(i, &ps))
== 0b111
}
/// Returns true when the [`Path`] seems like an [`Option`] type.
///
/// This function considers the following paths as Options:
/// - core::option::Option
/// - std::option::Option
/// - Option::*
///
/// Users can define their own [`Option`] type and this will return true - this is unavoidable.
fn is_path_an_option(path: &Path) -> bool {
is_path_segments_an_option(path.segments.iter().take(3).map(|ps| ps.ident.to_string()))
}
impl TryFrom<Field> for PropField {
type Error = Error;
@ -223,3 +253,25 @@ impl PartialEq for PropField {
self.name == other.name
}
}
#[cfg(test)]
mod tests {
use crate::derive_props::field::is_path_segments_an_option;
#[test]
fn all_std_and_core_option_path_seg_return_true() {
assert!(is_path_segments_an_option(
vec!["core".to_owned(), "option".to_owned(), "Option".to_owned()].into_iter()
));
assert!(is_path_segments_an_option(
vec!["std".to_owned(), "option".to_owned(), "Option".to_owned()].into_iter()
));
assert!(is_path_segments_an_option(
vec!["Option".to_owned()].into_iter()
));
// why OR instead of XOR
assert!(is_path_segments_an_option(
vec!["Option".to_owned(), "Vec".to_owned(), "Option".to_owned()].into_iter()
));
}
}

View File

@ -108,7 +108,7 @@ impl ToTokens for HtmlComponent {
let value = &node_ref.value;
quote_spanned! {value.span()=> #value }
} else {
quote! { ::yew::html::NodeRef::default() }
quote! { <::yew::html::NodeRef as ::std::default::Default>::default() }
};
let key = if let Some(key) = &special_props.key {
@ -118,7 +118,7 @@ impl ToTokens for HtmlComponent {
Some(::std::convert::Into::<::yew::virtual_dom::Key>::into(#value))
}
} else {
quote! { None }
quote! { ::std::option::Option::None }
};
tokens.extend(quote_spanned! {ty.span()=>

View File

@ -171,7 +171,7 @@ impl ToTokens for HtmlElement {
::std::borrow::Cow::<'static, str>::Borrowed(#key)
)
} else {
None
::std::option::Option::None
}
}),
},

View File

@ -1,41 +1,38 @@
#![no_implicit_prelude]
#![recursion_limit = "128"]
use yew::prelude::*;
mod t1 {
use super::*;
#[derive(Clone, Properties, PartialEq)]
pub struct Props<T: Clone + Default + PartialEq> {
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
pub struct Props<T: ::std::clone::Clone + ::std::default::Default + ::std::cmp::PartialEq> {
#[prop_or_default]
value: T,
}
fn optional_prop_generics_should_work() {
use ::yew::Properties;
Props::<bool>::builder().build();
Props::<bool>::builder().value(true).build();
}
}
mod t2 {
use super::*;
#[derive(Clone, PartialEq)]
#[derive(::std::clone::Clone, ::std::cmp::PartialEq)]
struct Value;
#[derive(Clone, Properties, PartialEq)]
pub struct Props<T: Clone + PartialEq> {
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
pub struct Props<T: ::std::clone::Clone + ::std::cmp::PartialEq> {
value: T,
}
fn required_prop_generics_should_work() {
use ::yew::Properties;
Props::<Value>::builder().value(Value).build();
}
}
mod t3 {
use super::*;
#[derive(Clone, Properties, PartialEq)]
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
pub struct Props {
b: i32,
#[prop_or_default]
@ -43,40 +40,46 @@ mod t3 {
}
fn order_is_alphabetized() {
use ::yew::Properties;
Props::builder().b(1).build();
Props::builder().a(1).b(2).build();
}
}
mod t4 {
use super::*;
#[derive(Clone, Properties, PartialEq)]
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
pub struct Props<T>
where
T: Clone + Default + PartialEq,
T: ::std::clone::Clone + ::std::default::Default + ::std::cmp::PartialEq,
{
#[prop_or_default]
value: T,
}
fn optional_prop_generics_should_work() {
use ::yew::Properties;
Props::<bool>::builder().build();
Props::<bool>::builder().value(true).build();
}
}
mod t5 {
use super::*;
#[derive(Clone, Properties, PartialEq)]
pub struct Props<'a, T: Clone + Default + PartialEq + 'a> {
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
pub struct Props<
'a,
T: ::std::clone::Clone + ::std::default::Default + ::std::cmp::PartialEq + 'a,
> {
#[prop_or_default]
static_value: &'static str,
value: &'a T,
}
fn optional_prop_generics_with_lifetime_should_work() {
use ::std::{convert::From, string::String};
use ::yew::Properties;
Props::<String>::builder().value(&String::from("")).build();
Props::<String>::builder()
.static_value("")
@ -86,18 +89,18 @@ mod t5 {
}
mod t6 {
use super::*;
use std::str::FromStr;
#[derive(Properties, Clone, PartialEq)]
pub struct Props<T: FromStr + Clone + PartialEq>
#[derive(::yew::Properties, ::std::clone::Clone, ::std::cmp::PartialEq)]
pub struct Props<T: ::std::str::FromStr + ::std::clone::Clone + ::std::cmp::PartialEq>
where
<T as FromStr>::Err: Clone + PartialEq,
<T as ::std::str::FromStr>::Err: ::std::clone::Clone + ::std::cmp::PartialEq,
{
value: Result<T, <T as FromStr>::Err>,
value: ::std::result::Result<T, <T as ::std::str::FromStr>::Err>,
}
fn required_prop_generics_with_where_clause_should_work() {
use ::std::{convert::From, result::Result::Ok, string::String};
use ::yew::Properties;
Props::<String>::builder()
.value(Ok(String::from("")))
.build();
@ -105,21 +108,22 @@ mod t6 {
}
mod t7 {
use super::*;
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(::std::clone::Clone, Debug, Eq, ::std::cmp::PartialEq)]
pub enum Foo {
One,
Two,
}
#[derive(Clone, Properties, PartialEq)]
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
pub struct Props {
#[prop_or(Foo::One)]
value: Foo,
}
fn prop_or_value_should_work() {
use ::std::assert_eq;
use ::yew::Properties;
let props = Props::builder().build();
assert_eq!(props.value, Foo::One);
Props::builder().value(Foo::Two).build();
@ -127,15 +131,16 @@ mod t7 {
}
mod t8 {
use super::*;
#[derive(Clone, Properties, PartialEq)]
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
pub struct Props {
#[prop_or_else(|| 123)]
value: i32,
}
fn prop_or_else_closure_should_work() {
use ::std::assert_eq;
use ::yew::Properties;
let props = Props::builder().build();
assert_eq!(props.value, 123);
Props::builder().value(123).build();
@ -143,26 +148,27 @@ mod t8 {
}
mod t9 {
use super::*;
use std::str::FromStr;
#[derive(Clone, Properties, PartialEq)]
pub struct Props<T: FromStr + Clone + PartialEq>
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
pub struct Props<T: ::std::str::FromStr + ::std::clone::Clone + ::std::cmp::PartialEq>
where
<T as FromStr>::Err: Clone + PartialEq,
<T as ::std::str::FromStr>::Err: ::std::clone::Clone + ::std::cmp::PartialEq,
{
#[prop_or_else(default_value)]
value: Result<T, <T as FromStr>::Err>,
value: ::std::result::Result<T, <T as ::std::str::FromStr>::Err>,
}
fn default_value<T: FromStr + Clone>() -> Result<T, <T as FromStr>::Err>
fn default_value<T: ::std::str::FromStr + ::std::clone::Clone>(
) -> ::std::result::Result<T, <T as ::std::str::FromStr>::Err>
where
<T as FromStr>::Err: Clone,
<T as ::std::str::FromStr>::Err: ::std::clone::Clone,
{
"123".parse()
}
fn prop_or_else_function_with_generics_should_work() {
use ::std::{assert_eq, result::Result::Ok};
use ::yew::Properties;
let props = Props::<i32>::builder().build();
assert_eq!(props.value, Ok(123));
Props::<i32>::builder().value(Ok(456)).build();
@ -170,15 +176,13 @@ mod t9 {
}
mod t10 {
use super::*;
// this test makes sure that Yew handles generic params with default values properly.
#[derive(Clone, Properties, PartialEq)]
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
pub struct Foo<S, M = S>
where
S: Clone + PartialEq,
M: Clone + PartialEq,
S: ::std::clone::Clone + ::std::cmp::PartialEq,
M: ::std::clone::Clone + ::std::cmp::PartialEq,
{
bar: S,
baz: M,
@ -186,28 +190,26 @@ mod t10 {
}
mod t11 {
use super::*;
// this test makes sure that Yew handles generic params with const generics properly.
#[derive(Clone, Properties, PartialEq)]
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
pub struct Foo<T, const N: usize>
where
T: Clone + PartialEq,
T: ::std::clone::Clone + ::std::cmp::PartialEq,
{
bar: [T; N],
}
}
mod t12 {
use super::*;
#[derive(Clone, Properties, PartialEq)]
pub struct Props<T: Clone + PartialEq> {
value: Option<T>,
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
pub struct Props<T: ::std::clone::Clone + ::std::cmp::PartialEq> {
value: ::std::option::Option<T>,
}
fn optional_prop_generics_should_work() {
use ::yew::Properties;
Props::<bool>::builder().build();
Props::<bool>::builder().value(true).build();
}

View File

@ -2,6 +2,6 @@
#[rustversion::attr(stable(1.51), test)]
fn tests() {
let t = trybuild::TestCases::new();
t.pass("tests/function_attr/*-pass.rs");
t.compile_fail("tests/function_attr/*-fail.rs");
t.pass("tests/function_component_attr/*-pass.rs");
t.compile_fail("tests/function_component_attr/*-fail.rs");
}

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::function_component;
#[derive(Clone, Properties, PartialEq)]
struct Props {

View File

@ -1,5 +1,5 @@
error: `function_component` attribute can only be applied to functions
--> $DIR/applied-to-non-fn-fail.rs:10:1
|
10 | struct Test;
| ^^^^^^^^^^^^
--> $DIR/applied-to-non-fn-fail.rs:9:1
|
9 | struct Test;
| ^^^^^^^^^^^^

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::{function_component};
#[derive(Clone, Properties, PartialEq)]
struct Props {

View File

@ -1,5 +1,5 @@
error: function components can't be async
--> $DIR/async-fail.rs:10:1
|
10 | async fn comp(props: &Props) -> Html {
| ^^^^^
--> $DIR/async-fail.rs:9:1
|
9 | async fn comp(props: &Props) -> Html {
| ^^^^^

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::function_component;
#[derive(Clone, Properties, PartialEq)]
struct Props {

View File

@ -1,23 +1,23 @@
error: expected identifier
--> $DIR/bad-name-fail.rs:9:22
--> $DIR/bad-name-fail.rs:8:22
|
9 | #[function_component(let)]
8 | #[function_component(let)]
| ^^^
error: unexpected token
--> $DIR/bad-name-fail.rs:18:23
--> $DIR/bad-name-fail.rs:17:23
|
18 | #[function_component(x, y, z)]
17 | #[function_component(x, y, z)]
| ^
error: expected identifier
--> $DIR/bad-name-fail.rs:27:22
--> $DIR/bad-name-fail.rs:26:22
|
27 | #[function_component(124)]
26 | #[function_component(124)]
| ^^^
error: the component must not have the same name as the function
--> $DIR/bad-name-fail.rs:36:22
--> $DIR/bad-name-fail.rs:35:22
|
36 | #[function_component(component)]
35 | #[function_component(component)]
| ^^^^^^^^^

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::function_component;
#[derive(Clone, Properties, PartialEq)]
struct Props {

View File

@ -1,5 +1,5 @@
error: expected a reference to a `Properties` type (try: `&Props`)
--> $DIR/bad-props-param-fail.rs:10:16
|
10 | fn comp(props: Props) -> Html {
| ^^^^^
--> $DIR/bad-props-param-fail.rs:9:16
|
9 | fn comp(props: Props) -> Html {
| ^^^^^

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::function_component;
#[derive(Clone, Properties, PartialEq)]
struct Props {

View File

@ -1,13 +1,13 @@
error: function components must return `yew::Html`
--> $DIR/bad-return-type-fail.rs:10:1
|
10 | fn comp_1(_props: &Props) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
--> $DIR/bad-return-type-fail.rs:9:1
|
9 | fn comp_1(_props: &Props) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/bad-return-type-fail.rs:14:5
--> $DIR/bad-return-type-fail.rs:13:5
|
13 | fn comp(_props: &Props) -> u32 {
12 | fn comp(_props: &Props) -> u32 {
| --- expected `VNode` because of return type
14 | 1
13 | 1
| ^ expected enum `VNode`, found integer

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::function_component;
#[derive(Clone, Properties, PartialEq)]
struct Props {

View File

@ -1,5 +1,5 @@
error: const functions can't be function components
--> $DIR/const-fail.rs:10:1
|
10 | const fn comp(props: &Props) -> Html {
| ^^^^^
--> $DIR/const-fail.rs:9:1
|
9 | const fn comp(props: &Props) -> Html {
| ^^^^^

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::function_component;
#[derive(Clone, Properties, PartialEq)]
struct Props {

View File

@ -1,5 +1,5 @@
error: extern functions can't be function components
--> $DIR/extern-fail.rs:10:1
|
10 | extern "C" fn comp(props: &Props) -> Html {
| ^^^^^^^^^^
--> $DIR/extern-fail.rs:9:1
|
9 | extern "C" fn comp(props: &Props) -> Html {
| ^^^^^^^^^^

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::function_component;
#[derive(Clone, Properties, PartialEq)]
struct Props {
@ -8,7 +7,6 @@ struct Props {
#[function_component(Comp)]
fn comp<'a>(props: &'a Props) -> Html {
html! {
<p>
{ props.a }

View File

@ -1,5 +1,5 @@
error: function components can't have generic lifetime parameters
--> $DIR/generic-lifetime-fail.rs:10:8
|
10 | fn comp<'a>(props: &'a Props) -> Html {
| ^^^^
--> $DIR/generic-lifetime-fail.rs:9:8
|
9 | fn comp<'a>(props: &'a Props) -> Html {
| ^^^^

View File

@ -1,26 +1,28 @@
#[derive(Clone, ::yew::Properties, PartialEq)]
#![no_implicit_prelude]
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
struct Props {
a: usize,
}
#[::yew_functional::function_component(Comp)]
#[::yew::function_component(Comp)]
fn comp<P>(_props: &P) -> ::yew::Html
where
P: ::yew::Properties + PartialEq,
P: ::yew::Properties + ::std::cmp::PartialEq,
{
::yew::html! {
<p></p>
}
}
#[::yew_functional::function_component(Comp1)]
#[::yew::function_component(Comp1)]
fn comp1<T1, T2>(_props: &()) -> ::yew::Html {
::yew::html! {
<p></p>
}
}
#[::yew_functional::function_component(ConstGenerics)]
#[::yew::function_component(ConstGenerics)]
fn const_generics<const N: i32>() -> ::yew::Html {
::yew::html! {
<div>

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::function_component;
#[derive(Clone, Properties, PartialEq)]
struct Props {

View File

@ -1,66 +1,57 @@
error[E0412]: cannot find type `INVALID` in this scope
--> $DIR/generic-props-fail.rs:26:19
--> $DIR/generic-props-fail.rs:25:19
|
21 | fn compile_fail() {
20 | fn compile_fail() {
| - help: you might be missing a type parameter: `<INVALID>`
...
26 | html! { <Comp<INVALID> /> };
25 | html! { <Comp<INVALID> /> };
| ^^^^^^^ not found in this scope
error[E0599]: no method named `build` found for struct `PropsBuilder<PropsBuilderStep_missing_required_prop_a>` in the current scope
--> $DIR/generic-props-fail.rs:23:14
--> $DIR/generic-props-fail.rs:22:14
|
4 | #[derive(Clone, Properties, PartialEq)]
3 | #[derive(Clone, Properties, PartialEq)]
| ---------- method `build` not found for this
...
23 | html! { <Comp<Props> /> };
22 | html! { <Comp<Props> /> };
| ^^^^ method not found in `PropsBuilder<PropsBuilderStep_missing_required_prop_a>`
error[E0599]: the function or associated item `new` exists for struct `VChild<FunctionComponent<comp<MissingTypeBounds>>>`, but its trait bounds were not satisfied
--> $DIR/generic-props-fail.rs:28:14
--> $DIR/generic-props-fail.rs:27:14
|
28 | html! { <Comp<MissingTypeBounds> /> };
27 | html! { <Comp<MissingTypeBounds> /> };
| ^^^^ function or associated item cannot be called on `VChild<FunctionComponent<comp<MissingTypeBounds>>>` due to unsatisfied trait bounds
|
::: $WORKSPACE/packages/yew-functional/src/lib.rs:73:1
::: $WORKSPACE/packages/yew/src/functional/mod.rs
|
73 | pub struct FunctionComponent<T: FunctionProvider + 'static> {
| pub struct FunctionComponent<T: FunctionProvider + 'static> {
| ----------------------------------------------------------- doesn't satisfy `_: yew::Component`
|
= note: the following trait bounds were not satisfied:
`FunctionComponent<comp<MissingTypeBounds>>: yew::Component`
error[E0277]: the trait bound `MissingTypeBounds: yew::Properties` is not satisfied
--> $DIR/generic-props-fail.rs:28:14
--> $DIR/generic-props-fail.rs:27:14
|
28 | html! { <Comp<MissingTypeBounds> /> };
27 | html! { <Comp<MissingTypeBounds> /> };
| ^^^^ the trait `yew::Properties` is not implemented for `MissingTypeBounds`
|
= note: required because of the requirements on the impl of `FunctionProvider` for `comp<MissingTypeBounds>`
error[E0277]: can't compare `MissingTypeBounds` with `MissingTypeBounds`
--> $DIR/generic-props-fail.rs:28:14
|
28 | html! { <Comp<MissingTypeBounds> /> };
| ^^^^ no implementation for `MissingTypeBounds == MissingTypeBounds`
|
= help: the trait `PartialEq` is not implemented for `MissingTypeBounds`
= note: required because of the requirements on the impl of `FunctionProvider` for `comp<MissingTypeBounds>`
error[E0107]: missing generics for type alias `Comp`
--> $DIR/generic-props-fail.rs:31:14
--> $DIR/generic-props-fail.rs:30:14
|
31 | html! { <Comp /> };
30 | html! { <Comp /> };
| ^^^^ expected 1 type argument
|
note: type alias defined here, with 1 type parameter: `P`
--> $DIR/generic-props-fail.rs:9:22
--> $DIR/generic-props-fail.rs:8:22
|
9 | #[function_component(Comp)]
8 | #[function_component(Comp)]
| ^^^^
10 | fn comp<P>(_props: &P) -> Html
9 | fn comp<P>(_props: &P) -> Html
| -
help: use angle brackets to add missing type argument
|
31 | html! { <Comp<P> /> };
30 | html! { <Comp<P> /> };
| ^^^

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::function_component;
#[derive(Clone, Properties, PartialEq)]
struct Props {

View File

@ -1,5 +1,5 @@
error: reference must not have a lifetime
--> $DIR/lifetime-props-param-fail.rs:10:17
|
10 | fn comp(props: &'static Props) -> Html {
| ^^^^^^^
--> $DIR/lifetime-props-param-fail.rs:9:17
|
9 | fn comp(props: &'static Props) -> Html {
| ^^^^^^^

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::function_component;
#[derive(Clone, Properties, PartialEq)]
struct Props {

View File

@ -1,11 +1,11 @@
error: function components can accept at most one parameter for the props
--> $DIR/multiple-param-fail.rs:10:24
|
10 | fn comp(props: &Props, invalid: String) -> Html {
| ^^^^^^^^^^^^^^^
--> $DIR/multiple-param-fail.rs:9:24
|
9 | fn comp(props: &Props, invalid: String) -> Html {
| ^^^^^^^^^^^^^^^
error: function components can accept at most one parameter for the props
--> $DIR/multiple-param-fail.rs:20:25
--> $DIR/multiple-param-fail.rs:19:25
|
20 | fn comp3(props: &Props, invalid: String, another_invalid: u32) -> Html {
19 | fn comp3(props: &Props, invalid: String, another_invalid: u32) -> Html {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::function_component;
#[derive(Clone, Properties, PartialEq)]
struct Props {

View File

@ -1,5 +1,5 @@
error: reference must not be mutable
--> $DIR/mut-ref-props-param-fail.rs:10:17
|
10 | fn comp(props: &mut Props) -> Html {
| ^^^
--> $DIR/mut-ref-props-param-fail.rs:9:17
|
9 | fn comp(props: &mut Props) -> Html {
| ^^^

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::function_component;
#[derive(Clone, Properties, PartialEq)]
struct Props {

View File

@ -1,7 +1,7 @@
error: unexpected end of input, expected identifier for the component
--> $DIR/no-name-fail.rs:9:1
--> $DIR/no-name-fail.rs:8:1
|
9 | #[function_component()]
8 | #[function_component()]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@ -1,9 +1,11 @@
#![no_implicit_prelude]
#[derive(Clone, ::yew::Properties, PartialEq)]
struct Props {
a: usize,
}
#[::yew_functional::function_component(Comp)]
#[::yew::function_component(Comp)]
fn comp(props: &Props) -> ::yew::Html {
::yew::html! {
<p>

View File

@ -1,5 +1,4 @@
use yew::prelude::*;
use yew_functional::function_component;
#[derive(Clone, Properties, PartialEq)]
struct Props {

View File

@ -1,5 +1,5 @@
error: function components can't accept a receiver
--> $DIR/with-receiver-fail.rs:13:13
--> $DIR/with-receiver-fail.rs:12:13
|
13 | fn comp(self, props: &Props) -> Html {
12 | fn comp(self, props: &Props) -> Html {
| ^^^^

View File

@ -1,4 +1,6 @@
#[::yew_functional::function_component(Comp)]
#![no_implicit_prelude]
#[::yew::function_component(Comp)]
fn comp() -> ::yew::Html {
::yew::html! {
<p>

View File

@ -1,110 +1,108 @@
use yew::html::ChildrenRenderer;
use yew::prelude::*;
use yew::virtual_dom::{VChild, VNode};
#![no_implicit_prelude]
#[derive(Clone, Properties, Default, PartialEq)]
#[derive(::std::clone::Clone, ::yew::Properties, ::std::default::Default, ::std::cmp::PartialEq)]
pub struct ContainerProperties {
pub int: i32,
#[prop_or_default]
pub children: Children,
pub children: ::yew::Children,
}
pub struct Container;
impl Component for Container {
impl ::yew::Component for Container {
type Message = ();
type Properties = ContainerProperties;
fn create(_ctx: &Context<Self>) -> Self {
unimplemented!()
fn create(_ctx: &::yew::Context<Self>) -> Self {
::std::unimplemented!()
}
fn view(&self, _ctx: &Context<Self>) -> Html {
unimplemented!()
fn view(&self, _ctx: &::yew::Context<Self>) -> ::yew::Html {
::std::unimplemented!()
}
}
#[derive(Clone, PartialEq)]
#[derive(::std::clone::Clone, ::std::cmp::PartialEq)]
pub enum ChildrenVariants {
Child(VChild<Child>),
AltChild(VChild<AltChild>),
Child(::yew::virtual_dom::VChild<Child>),
AltChild(::yew::virtual_dom::VChild<AltChild>),
}
impl From<VChild<Child>> for ChildrenVariants {
fn from(comp: VChild<Child>) -> Self {
impl ::std::convert::From<::yew::virtual_dom::VChild<Child>> for ChildrenVariants {
fn from(comp: ::yew::virtual_dom::VChild<Child>) -> Self {
ChildrenVariants::Child(comp)
}
}
impl From<VChild<AltChild>> for ChildrenVariants {
fn from(comp: VChild<AltChild>) -> Self {
impl ::std::convert::From<::yew::virtual_dom::VChild<AltChild>> for ChildrenVariants {
fn from(comp: ::yew::virtual_dom::VChild<AltChild>) -> Self {
ChildrenVariants::AltChild(comp)
}
}
impl Into<VNode> for ChildrenVariants {
fn into(self) -> VNode {
impl ::std::convert::Into<::yew::virtual_dom::VNode> for ChildrenVariants {
fn into(self) -> ::yew::virtual_dom::VNode {
match self {
Self::Child(comp) => VNode::VComp(comp.into()),
Self::AltChild(comp) => VNode::VComp(comp.into()),
Self::Child(comp) => ::yew::virtual_dom::VNode::VComp(::std::convert::Into::<::yew::virtual_dom::VComp>::into(comp)),
Self::AltChild(comp) => ::yew::virtual_dom::VNode::VComp(::std::convert::Into::<::yew::virtual_dom::VComp>::into(comp)),
}
}
}
#[derive(Clone, Properties, Default, PartialEq)]
#[derive(::std::clone::Clone, ::yew::Properties, ::std::default::Default, ::std::cmp::PartialEq)]
pub struct ChildProperties {
#[prop_or_default]
pub string: String,
pub string: ::std::string::String,
pub int: i32,
#[prop_or_default]
pub opt_str: Option<String>,
pub opt_str: ::std::option::Option<::std::string::String>,
#[prop_or_default]
pub vec: Vec<i32>,
pub vec: ::std::vec::Vec<i32>,
#[prop_or_default]
pub optional_callback: Option<Callback<()>>,
pub optional_callback: ::std::option::Option<::yew::Callback<()>>,
}
pub struct Child;
impl Component for Child {
impl ::yew::Component for Child {
type Message = ();
type Properties = ChildProperties;
fn create(_ctx: &Context<Self>) -> Self {
unimplemented!()
fn create(_ctx: &::yew::Context<Self>) -> Self {
::std::unimplemented!()
}
fn view(&self, _ctx: &Context<Self>) -> Html {
unimplemented!()
fn view(&self, _ctx: &::yew::Context<Self>) -> ::yew::Html {
::std::unimplemented!()
}
}
pub struct AltChild;
impl Component for AltChild {
impl ::yew::Component for AltChild {
type Message = ();
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
unimplemented!()
fn create(_ctx: &::yew::Context<Self>) -> Self {
::std::unimplemented!()
}
fn view(&self, _ctx: &Context<Self>) -> Html {
unimplemented!()
fn view(&self, _ctx: &::yew::Context<Self>) -> ::yew::Html {
::std::unimplemented!()
}
}
#[derive(Clone, Properties, Default, PartialEq)]
#[derive(::std::clone::Clone, ::yew::Properties, ::std::default::Default, ::std::cmp::PartialEq)]
pub struct ChildContainerProperties {
pub int: i32,
#[prop_or_default]
pub children: ChildrenRenderer<ChildrenVariants>,
pub children: ::yew::html::ChildrenRenderer<ChildrenVariants>,
}
pub struct ChildContainer;
impl Component for ChildContainer {
impl ::yew::Component for ChildContainer {
type Message = ();
type Properties = ChildContainerProperties;
fn create(_ctx: &Context<Self>) -> Self {
unimplemented!()
fn create(_ctx: &::yew::Context<Self>) -> Self {
::std::unimplemented!()
}
fn view(&self, _ctx: &Context<Self>) -> Html {
unimplemented!()
fn view(&self, _ctx: &::yew::Context<Self>) -> ::yew::Html {
::std::unimplemented!()
}
}
@ -114,78 +112,77 @@ mod scoped {
}
fn compile_pass() {
html! { <Child int=1 /> };
::yew::html! { <Child int=1 /> };
html! {
::yew::html! {
<>
<Child int=1 />
<scoped::Child int=1 />
</>
};
let props = <Child as Component>::Properties::default();
let node_ref = NodeRef::default();
html! {
let props = <<Child as ::yew::Component>::Properties as ::std::default::Default>::default();
let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
<>
<Child with props />
<Child ref={node_ref.clone()} with yew::props!(Child::Properties { int: 5 }) />
<Child with <Child as Component>::Properties::default() ref={node_ref} />
<Child ref={::std::clone::Clone::clone(&node_ref)} with ::yew::props!(Child::Properties { int: 5 }) />
<Child with <<Child as ::yew::Component>::Properties as ::std::default::Default>::default() ref={node_ref} />
</>
};
html! {
::yew::html! {
<>
<Child int=1 string="child" />
<Child int=1 />
<Child int={1+1} />
<Child int=1 vec={vec![1]} />
<Child string={String::from("child")} int=1 />
<Child int=1 vec={::std::vec![1]} />
<Child string={<::std::string::String as ::std::convert::From<&'static str>>::from("child")} int=1 />
<Child opt_str="child" int=1 />
<Child opt_str={String::from("child")} int=1 />
<Child opt_str={Some("child")} int=1 />
<Child opt_str={Some(String::from("child"))} int=1 />
<Child opt_str={<::std::string::String as ::std::convert::From<&'static str>>::from("child")} int=1 />
<Child opt_str={::std::option::Option::Some("child")} int=1 />
<Child opt_str={::std::option::Option::Some(<::std::string::String as ::std::convert::From<&'static str>>::from("child"))} int=1 />
</>
};
let name_expr = "child";
html! {
::yew::html! {
<Child int=1 string={name_expr} />
};
let string = "child";
let int = 1;
html! {
::yew::html! {
<Child {int} {string} />
};
html! {
::yew::html! {
<>
<Child int=1 />
<Child int=1 optional_callback={Some(Callback::from(|_| ()))} />
<Child int=1 optional_callback={Callback::from(|_| ())} />
<Child int=1 optional_callback={None::<Callback<_>>} />
<Child int=1 optional_callback={::std::option::Option::Some(<::yew::Callback<()> as ::std::convert::From<_>>::from(|_| ()))} />
<Child int=1 optional_callback={<::yew::Callback<()> as ::std::convert::From<_>>::from(|_| ())} />
<Child int=1 optional_callback={::std::option::Option::None::<::yew::Callback<_>>} />
</>
};
let node_ref = NodeRef::default();
html! {
let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
<>
<Child int=1 ref={node_ref} />
</>
};
let int = 1;
let node_ref = NodeRef::default();
html! {
let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
<>
<Child {int} ref={node_ref} />
</>
};
let props = <Container as Component>::Properties::default();
html! {
let props = <<Container as ::yew::Component>::Properties as ::std::default::Default>::default();
::yew::html! {
<>
<Container int=1 />
<Container int=1></Container>
@ -202,13 +199,13 @@ fn compile_pass() {
<scoped::Container int=2/>
</scoped::Container>
<Container int=1 children={ChildrenRenderer::new(
vec![html!{ "String" }]
<Container int=1 children={::yew::html::ChildrenRenderer::new(
::std::vec![::yew::html!{ "::std::string::String" }]
)} />
</>
};
html! {
::yew::html! {
<>
<ChildContainer int=1 />
<ChildContainer int=1></ChildContainer>
@ -217,76 +214,85 @@ fn compile_pass() {
</>
};
html! {
::yew::html! {
<ChildContainer int=1>
<AltChild />
<Child int=1 />
{
html_nested! {
::yew::html_nested! {
<Child int=1 />
}
}
{
(0..2)
.map(|i| { html_nested! { <Child int={i} /> } })
.collect::<Vec<_>>()
::std::iter::Iterator::collect::<::std::vec::Vec<_>>(
::std::iter::Iterator::map(0..2,
|i| { ::yew::html_nested! { <Child int={i} /> } })
)
}
</ChildContainer>
};
let children = vec![
html_nested! { <Child int=1 /> },
html_nested! { <Child int=2 /> },
let children = ::std::vec![
::yew::html_nested! { <Child int=1 /> },
::yew::html_nested! { <Child int=2 /> },
];
html! {
::yew::html! {
<ChildContainer int=1>
{ children.clone() }
{ ::std::clone::Clone::clone(&children) }
</ChildContainer>
};
// https://github.com/yewstack/yew/issues/1527
html! {
::yew::html! {
<ChildContainer int=1>
{ for children }
</ChildContainer>
};
let variants = || -> Vec<ChildrenVariants> {
vec![
ChildrenVariants::Child(VChild::new(
ChildProperties::default(),
NodeRef::default(),
None,
let variants = || -> ::std::vec::Vec<ChildrenVariants> {
::std::vec![
ChildrenVariants::Child(::yew::virtual_dom::VChild::new(
<ChildProperties as ::std::default::Default>::default(),
<::yew::NodeRef as ::std::default::Default>::default(),
::std::option::Option::None,
)),
ChildrenVariants::AltChild(::yew::virtual_dom::VChild::new(
(),
<::yew::NodeRef as ::std::default::Default>::default(),
::std::option::Option::None
)),
ChildrenVariants::AltChild(VChild::new((), NodeRef::default(), None)),
]
};
html! {
::yew::html! {
<>
{
variants()
.into_iter()
.filter(|c| match c {
ChildrenVariants::Child(_) => true,
_ => false,
})
.collect::<VNode>()
::std::iter::Iterator::collect::<::yew::virtual_dom::VNode>(
::std::iter::Iterator::filter(
::std::iter::IntoIterator::into_iter(variants()),
|c| match c {
ChildrenVariants::Child(_) => true,
_ => false,
}
)
)
}
<div>
{
variants()
.into_iter()
.filter(|c| match c {
ChildrenVariants::AltChild(_) => true,
_ => false,
})
.collect::<VNode>()
::std::iter::Iterator::collect::<::yew::virtual_dom::VNode>(
::std::iter::Iterator::filter(
::std::iter::IntoIterator::into_iter(variants()),
|c| match c {
ChildrenVariants::AltChild(_) => true,
_ => false,
}
)
)
}
</div>
</>
};
html_nested! { 1 };
::yew::html_nested! { 1 };
}
fn main() {}

View File

@ -1,30 +1,29 @@
use std::marker::PhantomData;
use yew::prelude::*;
#![no_implicit_prelude]
pub struct Generic<T> {
marker: PhantomData<T>,
marker: ::std::marker::PhantomData<T>,
}
impl<T> Component for Generic<T>
impl<T> ::yew::Component for Generic<T>
where
T: 'static,
{
type Message = ();
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
unimplemented!()
fn create(_ctx: &::yew::Context<Self>) -> Self {
::std::unimplemented!()
}
fn view(&self, _ctx: &Context<Self>) -> Html {
unimplemented!()
fn view(&self, _ctx: &::yew::Context<Self>) -> ::yew::Html {
::std::unimplemented!()
}
}
pub struct Generic2<T1, T2> {
marker: PhantomData<(T1, T2)>,
marker: ::std::marker::PhantomData<(T1, T2)>,
}
impl<T1, T2> Component for Generic2<T1, T2>
impl<T1, T2> ::yew::Component for Generic2<T1, T2>
where
T1: 'static,
T2: 'static,
@ -32,31 +31,31 @@ where
type Message = ();
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
unimplemented!()
fn create(_ctx: &::yew::Context<Self>) -> Self {
::std::unimplemented!()
}
fn view(&self, _ctx: &Context<Self>) -> Html {
unimplemented!()
fn view(&self, _ctx: &::yew::Context<Self>) -> ::yew::Html {
::std::unimplemented!()
}
}
fn compile_pass() {
html! { <Generic<String> /> };
html! { <Generic<String> ></Generic<String>> };
::yew::html! { <Generic<::std::string::String> /> };
::yew::html! { <Generic<::std::string::String> ></Generic<::std::string::String>> };
html! { <Generic<Vec<String>> /> };
html! { <Generic<Vec<String>>></ Generic<Vec<String>>> };
::yew::html! { <Generic<::std::vec::Vec<::std::string::String>> /> };
::yew::html! { <Generic<::std::vec::Vec<::std::string::String>>></ Generic<::std::vec::Vec<::std::string::String>>> };
html! { <Generic<usize> /> };
html! { <Generic<usize>></Generic<usize>> };
html! { <Generic<String, > /> };
html! { <Generic<String, >></Generic<String,>> };
::yew::html! { <Generic<usize> /> };
::yew::html! { <Generic<usize>></Generic<usize>> };
::yew::html! { <Generic<::std::string::String, > /> };
::yew::html! { <Generic<::std::string::String, >></Generic<::std::string::String,>> };
html! { <Generic2<String, String> /> };
html! { <Generic2<String, String>></Generic2<String, String>> };
::yew::html! { <Generic2<::std::string::String, ::std::string::String> /> };
::yew::html! { <Generic2<::std::string::String, ::std::string::String>></Generic2<::std::string::String, ::std::string::String>> };
html! { <Generic2<String, String, > /> };
html! { <Generic2<String, String, >></Generic2<String, String, >> };
::yew::html! { <Generic2<::std::string::String, ::std::string::String, > /> };
::yew::html! { <Generic2<::std::string::String, ::std::string::String, >></Generic2<::std::string::String, ::std::string::String, >> };
}
fn main() {}

View File

@ -1,16 +1,18 @@
use std::borrow::Cow;
use yew::prelude::*;
#![no_implicit_prelude]
fn compile_pass() {
let onclick = Callback::from(|_: MouseEvent| ());
let parent_ref = NodeRef::default();
let onclick = <::yew::Callback<::yew::MouseEvent> as ::std::convert::From<_>>::from(
|_: ::yew::MouseEvent| (),
);
let parent_ref = <::yew::NodeRef as ::std::default::Default>::default();
let dyn_tag = || String::from("test");
let mut extra_tags_iter = vec!["a", "b"].into_iter();
let dyn_tag = || <::std::string::String as ::std::convert::From<&str>>::from("test");
let mut extra_tags_iter = ::std::iter::IntoIterator::into_iter(::std::vec!["a", "b"]);
let cow_none: Option<Cow<'static, str>> = None;
let cow_none: ::std::option::Option<::std::borrow::Cow<'static, str>> =
::std::option::Option::None;
html! {
::yew::html! {
<div>
<div data-key="abc"></div>
<div ref={parent_ref} class="parent">
@ -40,7 +42,7 @@ fn compile_pass() {
</filter>
</defs>
</svg>
<img class={classes!("avatar", "hidden")} src="http://pic.com" />
<img class={::yew::classes!("avatar", "hidden")} src="http://pic.com" />
<img class="avatar hidden" />
<button onclick={&onclick} {onclick} />
<a href="http://google.com" />
@ -48,8 +50,8 @@ fn compile_pass() {
<custom-tag-b />
</custom-tag-a>
<@{dyn_tag()}>
<@{extra_tags_iter.next().unwrap()} class="extra-a"/>
<@{extra_tags_iter.next().unwrap()} class="extra-b"/>
<@{::std::iter::Iterator::next(&mut extra_tags_iter).unwrap()} class="extra-a"/>
<@{::std::iter::Iterator::next(&mut extra_tags_iter).unwrap()} class="extra-b"/>
</@>
<@{
@ -61,22 +63,24 @@ fn compile_pass() {
}
}/>
<a href={Some(Cow::Borrowed("http://google.com"))} media={cow_none.clone()} />
<track kind={Some(Cow::Borrowed("subtitles"))} src={cow_none.clone()} />
<track kind={Some(Cow::Borrowed("5"))} mixed="works" />
<input value={Some(Cow::Borrowed("value"))} onblur={Some(Callback::from(|_| ()))} />
<a href={::std::option::Option::Some(::std::borrow::Cow::Borrowed("http://google.com"))} media={::std::clone::Clone::clone(&cow_none)} />
<track kind={::std::option::Option::Some(::std::borrow::Cow::Borrowed("subtitles"))} src={::std::clone::Clone::clone(&cow_none)} />
<track kind={::std::option::Option::Some(::std::borrow::Cow::Borrowed("5"))} mixed="works" />
<input value={::std::option::Option::Some(::std::borrow::Cow::Borrowed("value"))}
onblur={::std::option::Option::Some(<::yew::Callback<::yew::FocusEvent> as ::std::convert::From<_>>::from(|_| ()))}
/>
</div>
};
let children = vec![
html! { <span>{ "Hello" }</span> },
html! { <span>{ "World" }</span> },
let children = ::std::vec![
::yew::html! { <span>{ "Hello" }</span> },
::yew::html! { <span>{ "World" }</span> },
];
html! { <div>{children}</div> };
::yew::html! { <div>{children}</div> };
// handle misleading angle brackets
html! { <div data-val={<String as Default>::default()}></div> };
html! { <div><a data-val={<String as Default>::default()} /></div> };
::yew::html! { <div data-val={<::std::string::String as ::std::default::Default>::default()}></div> };
::yew::html! { <div><a data-val={<::std::string::String as ::std::default::Default>::default()} /></div> };
}
fn main() {}

View File

@ -1,23 +1,23 @@
use yew::prelude::*;
#![no_implicit_prelude]
fn compile_pass() {
html! { "" };
html! { 'a' };
html! { "hello" };
html! { 42 };
html! { 1.234 };
::yew::html! { "" };
::yew::html! { 'a' };
::yew::html! { "hello" };
::yew::html! { 42 };
::yew::html! { 1.234 };
html! { <span>{ "" }</span> };
html! { <span>{ 'a' }</span> };
html! { <span>{ "hello" }</span> };
html! { <span>{ 42 }</span> };
html! { <span>{ 1.234 }</span> };
::yew::html! { <span>{ "" }</span> };
::yew::html! { <span>{ 'a' }</span> };
::yew::html! { <span>{ "hello" }</span> };
::yew::html! { <span>{ 42 }</span> };
::yew::html! { <span>{ 1.234 }</span> };
html! { format!("Hello") };
html! { String::from("Hello") };
::yew::html! { ::std::format!("Hello") };
::yew::html! { {<::std::string::String as ::std::convert::From<&str>>::from("Hello") } };
let msg = "Hello";
html! { msg };
::yew::html! { msg };
}
fn main() {}

View File

@ -1,6 +1,6 @@
use yew::prelude::*;
#![no_implicit_prelude]
#[derive(Clone, Properties, PartialEq)]
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
struct Props {
a: usize,
#[prop_or_default]
@ -8,9 +8,9 @@ struct Props {
}
fn compile_pass() {
yew::props!(Props { a: 5 });
::yew::props!(Props { a: 5 });
let (a, b) = (3, 5);
yew::props!(Props { a, b });
::yew::props!(Props { a, b });
}
fn main() {}

View File

@ -1,29 +1,29 @@
use yew::prelude::*;
#![no_implicit_prelude]
#[derive(Clone, Properties, PartialEq)]
#[derive(::std::clone::Clone, ::yew::Properties, ::std::cmp::PartialEq)]
struct Props {
n: i32,
}
struct MyComp;
impl Component for MyComp {
impl ::yew::Component for MyComp {
type Message = ();
type Properties = Props;
fn create(_ctx: &Context<Self>) -> Self {
unimplemented!()
fn create(_ctx: &::yew::Context<Self>) -> Self {
::std::unimplemented!()
}
fn view(&self, _ctx: &Context<Self>) -> Html {
unimplemented!()
fn view(&self, _ctx: &::yew::Context<Self>) -> ::yew::Html {
::std::unimplemented!()
}
}
fn compile_pass() {
yew::props!(Props { n: 1 });
yew::props!(self::Props { n: 1 });
yew::props!(MyComp::Properties { n: 2 });
yew::props!(self::MyComp::Properties { n: 3 });
yew::props!(<MyComp as Component>::Properties { n: 5 });
::yew::props!(Props { n: 1 });
::yew::props!(self::Props { n: 1 });
::yew::props!(MyComp::Properties { n: 2 });
::yew::props!(self::MyComp::Properties { n: 3 });
::yew::props!(<MyComp as ::yew::Component>::Properties { n: 5});
}
fn main() {}