Skip to main content

ide_assists/handlers/
generate_single_field_struct_from.rs

1use hir::next_solver::{DbInterner, TypingMode};
2use hir::{HasCrate, ModuleDef, Semantics};
3use ide_db::use_trivial_constructor::use_trivial_constructor_with_factory;
4use ide_db::{
5    RootDatabase, famous_defs::FamousDefs, helpers::mod_path_to_ast_with_factory,
6    imports::import_assets::item_for_path_search,
7};
8use syntax::syntax_editor::{Position, SyntaxEditor};
9use syntax::{
10    TokenText,
11    ast::{
12        self, AstNode, HasAttrs, HasGenericParams, HasName, edit::AstNodeEdit,
13        syntax_factory::SyntaxFactory,
14    },
15};
16
17use crate::{
18    AssistId,
19    assist_context::{AssistContext, Assists},
20};
21
22// Assist: generate_single_field_struct_from
23//
24// Implement From for a single field structure, ignore trivial types.
25//
26// ```
27// # //- minicore: from, phantom_data
28// use core::marker::PhantomData;
29// struct $0Foo<T> {
30//     id: i32,
31//     _phantom_data: PhantomData<T>,
32// }
33// ```
34// ->
35// ```
36// use core::marker::PhantomData;
37// struct Foo<T> {
38//     id: i32,
39//     _phantom_data: PhantomData<T>,
40// }
41//
42// impl<T> From<i32> for Foo<T> {
43//     fn from(id: i32) -> Self {
44//         Self { id, _phantom_data: PhantomData }
45//     }
46// }
47// ```
48pub(crate) fn generate_single_field_struct_from(
49    acc: &mut Assists,
50    ctx: &AssistContext<'_, '_>,
51) -> Option<()> {
52    let strukt_name = ctx.find_node_at_offset::<ast::Name>()?;
53    let adt = ast::Adt::cast(strukt_name.syntax().parent()?)?;
54    let ast::Adt::Struct(strukt) = adt else {
55        tracing::debug!(?adt);
56        return None;
57    };
58
59    let sema = &ctx.sema;
60    let (names, types) = get_fields(&strukt)?;
61
62    let module = sema.scope(strukt.syntax())?.module();
63    let constructors = make_constructors(ctx, module, &types);
64
65    if constructors.iter().filter(|expr| expr.is_none()).count() != 1 {
66        tracing::debug!(?constructors);
67        return None;
68    }
69    let main_field_i = constructors.iter().position(Option::is_none)?;
70    if from_impl_exists(&strukt, main_field_i, &ctx.sema).is_some() {
71        tracing::debug!(?strukt, ?main_field_i);
72        return None;
73    }
74
75    let main_field_name =
76        names.as_ref().map_or(TokenText::borrowed("value"), |names| names[main_field_i].text());
77    let main_field_ty = types[main_field_i].clone();
78
79    acc.add(
80        AssistId::generate("generate_single_field_struct_from"),
81        "Generate single field `From`",
82        strukt.syntax().text_range(),
83        |builder| {
84            let editor = builder.make_editor(strukt.syntax());
85            let make = editor.make();
86
87            let indent = strukt.indent_level();
88            let ty_where_clause = strukt.where_clause();
89            let type_gen_params = strukt.generic_param_list();
90            let type_gen_args = type_gen_params.as_ref().map(|params| params.to_generic_args(make));
91            let trait_gen_args = Some(make.generic_arg_list(
92                [ast::GenericArg::TypeArg(make.type_arg(main_field_ty.clone()))],
93                false,
94            ));
95
96            let ty = make.ty(&strukt_name.text());
97
98            let constructor =
99                make_adt_constructor(names.as_deref(), constructors, &main_field_name, make);
100            let body = make.block_expr([], Some(constructor));
101
102            let fn_ = make
103                .fn_(
104                    [],
105                    None,
106                    make.name("from"),
107                    None,
108                    None,
109                    make.param_list(
110                        None,
111                        [make.param(
112                            make.path_pat(make.path_from_text(&main_field_name)),
113                            main_field_ty,
114                        )],
115                    ),
116                    body,
117                    Some(make.ret_type(make.ty("Self"))),
118                    false,
119                    false,
120                    false,
121                    false,
122                )
123                .indent_with_mapping(1.into(), make);
124
125            let cfg_attrs =
126                strukt.attrs().filter(|attr| matches!(attr.meta(), Some(ast::Meta::CfgMeta(_))));
127
128            let impl_ = make.impl_trait(
129                cfg_attrs,
130                false,
131                None,
132                trait_gen_args,
133                type_gen_params,
134                type_gen_args,
135                false,
136                make.ty("From"),
137                ty.clone(),
138                None,
139                ty_where_clause.map(|wc| wc.reset_indent()),
140                None,
141            );
142
143            let (impl_editor, impl_root) = SyntaxEditor::with_ast_node(&impl_);
144            let assoc_list = impl_root.get_or_create_assoc_item_list_with_editor(&impl_editor);
145            assoc_list.add_items(&impl_editor, vec![fn_.into()]);
146            let impl_ = ast::Impl::cast(impl_editor.finish().new_root().clone())
147                .unwrap()
148                .indent_with_mapping(indent, make);
149
150            editor.insert_all(
151                Position::after(strukt.syntax()),
152                vec![
153                    make.whitespace(&format!("\n\n{indent}")).into(),
154                    impl_.syntax().clone().into(),
155                ],
156            );
157            builder.add_file_edits(ctx.vfs_file_id(), editor);
158        },
159    )
160}
161
162fn make_adt_constructor(
163    names: Option<&[ast::Name]>,
164    constructors: Vec<Option<ast::Expr>>,
165    main_field_name: &TokenText<'_>,
166    make: &SyntaxFactory,
167) -> ast::Expr {
168    if let Some(names) = names {
169        let fields = make.record_expr_field_list(names.iter().zip(constructors).map(
170            |(name, initializer)| make.record_expr_field(make.name_ref(&name.text()), initializer),
171        ));
172        make.record_expr(make.path_from_text("Self"), fields).into()
173    } else {
174        let arg_list = make.arg_list(constructors.into_iter().map(|expr| {
175            expr.unwrap_or_else(|| make.expr_path(make.path_from_text(main_field_name)))
176        }));
177        make.expr_call(make.expr_path(make.path_from_text("Self")), arg_list).into()
178    }
179}
180
181fn make_constructors(
182    ctx: &AssistContext<'_, '_>,
183    module: hir::Module,
184    types: &[ast::Type],
185) -> Vec<Option<ast::Expr>> {
186    let make = SyntaxFactory::without_mappings();
187    let (db, sema) = (ctx.db(), &ctx.sema);
188    let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate(ctx.sema.db)));
189    types
190        .iter()
191        .map(|ty| {
192            let ty = sema.resolve_type(ty)?;
193            if ty.is_unit() {
194                return Some(make.expr_tuple([]).into());
195            }
196            let item_in_ns = ModuleDef::Adt(ty.as_adt()?).into();
197            let edition = module.krate(db).edition(db);
198
199            let ty_path = module.find_path(db, item_for_path_search(db, item_in_ns)?, cfg)?;
200
201            use_trivial_constructor_with_factory(
202                &make,
203                db,
204                mod_path_to_ast_with_factory(&make, &ty_path, edition),
205                &ty,
206                edition,
207            )
208        })
209        .collect()
210}
211
212fn get_fields(strukt: &ast::Struct) -> Option<(Option<Vec<ast::Name>>, Vec<ast::Type>)> {
213    Some(match strukt.kind() {
214        ast::StructKind::Unit => return None,
215        ast::StructKind::Record(fields) => {
216            let names = fields.fields().map(|field| field.name()).collect::<Option<_>>()?;
217            let types = fields.fields().map(|field| field.ty()).collect::<Option<_>>()?;
218            (Some(names), types)
219        }
220        ast::StructKind::Tuple(fields) => {
221            (None, fields.fields().map(|field| field.ty()).collect::<Option<_>>()?)
222        }
223    })
224}
225
226#[tracing::instrument(ret)]
227fn from_impl_exists(
228    strukt: &ast::Struct,
229    main_field_i: usize,
230    sema: &Semantics<'_, RootDatabase>,
231) -> Option<()> {
232    let db = sema.db;
233    let strukt = sema.to_def(strukt)?;
234    let krate = strukt.krate(db);
235    let from_trait = FamousDefs(sema, krate).core_convert_From()?;
236    let interner = DbInterner::new_with(db, krate.base());
237    use hir::next_solver::infer::DbInternerInferExt;
238    let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
239
240    let strukt = strukt.instantiate_infer(&infcx);
241    let field_ty = strukt.fields(db).get(main_field_i)?.ty(db);
242    let struct_ty = strukt.ty(db);
243    tracing::debug!(?strukt, ?field_ty, ?struct_ty);
244    struct_ty.impls_trait(infcx, from_trait, &[field_ty]).then_some(())
245}
246
247#[cfg(test)]
248mod tests {
249    use crate::tests::{check_assist, check_assist_not_applicable};
250
251    use super::generate_single_field_struct_from;
252
253    #[test]
254    fn works() {
255        check_assist(
256            generate_single_field_struct_from,
257            r#"
258            //- minicore: from
259            struct $0Foo {
260                foo: i32,
261            }
262            "#,
263            r#"
264            struct Foo {
265                foo: i32,
266            }
267
268            impl From<i32> for Foo {
269                fn from(foo: i32) -> Self {
270                    Self { foo }
271                }
272            }
273            "#,
274        );
275        check_assist(
276            generate_single_field_struct_from,
277            r#"
278            //- minicore: from, phantom_data
279            struct $0Foo {
280                b1: (),
281                b2: core::marker::PhantomData,
282                foo: i32,
283                a1: (),
284                a2: core::marker::PhantomData,
285            }
286            "#,
287            r#"
288            struct Foo {
289                b1: (),
290                b2: core::marker::PhantomData,
291                foo: i32,
292                a1: (),
293                a2: core::marker::PhantomData,
294            }
295
296            impl From<i32> for Foo {
297                fn from(foo: i32) -> Self {
298                    Self { b1: (), b2: core::marker::PhantomData, foo, a1: (), a2: core::marker::PhantomData }
299                }
300            }
301            "#,
302        );
303    }
304
305    #[test]
306    fn cfgs() {
307        check_assist(
308            generate_single_field_struct_from,
309            r#"
310            //- minicore: from
311            #[cfg(feature = "foo")]
312            #[cfg(test)]
313            struct $0Foo {
314                foo: i32,
315            }
316            "#,
317            r#"
318            #[cfg(feature = "foo")]
319            #[cfg(test)]
320            struct Foo {
321                foo: i32,
322            }
323
324            #[cfg(feature = "foo")]
325            #[cfg(test)]
326            impl From<i32> for Foo {
327                fn from(foo: i32) -> Self {
328                    Self { foo }
329                }
330            }
331            "#,
332        );
333    }
334
335    #[test]
336    fn indent() {
337        check_assist(
338            generate_single_field_struct_from,
339            r#"
340            //- minicore: from
341            mod foo {
342                struct $0Foo {
343                    foo: i32,
344                }
345            }
346            "#,
347            r#"
348            mod foo {
349                struct Foo {
350                    foo: i32,
351                }
352
353                impl From<i32> for Foo {
354                    fn from(foo: i32) -> Self {
355                        Self { foo }
356                    }
357                }
358            }
359            "#,
360        );
361        check_assist(
362            generate_single_field_struct_from,
363            r#"
364            //- minicore: from
365            mod foo {
366                mod bar {
367                    struct $0Foo {
368                        foo: i32,
369                    }
370                }
371            }
372            "#,
373            r#"
374            mod foo {
375                mod bar {
376                    struct Foo {
377                        foo: i32,
378                    }
379
380                    impl From<i32> for Foo {
381                        fn from(foo: i32) -> Self {
382                            Self { foo }
383                        }
384                    }
385                }
386            }
387            "#,
388        );
389    }
390
391    #[test]
392    fn where_clause_indent() {
393        check_assist(
394            generate_single_field_struct_from,
395            r#"
396            //- minicore: from
397            mod foo {
398                mod bar {
399                    trait Trait {}
400                    struct $0Foo<T>
401                    where
402                        T: Trait,
403                    {
404                        foo: T,
405                    }
406                }
407            }
408            "#,
409            r#"
410            mod foo {
411                mod bar {
412                    trait Trait {}
413                    struct Foo<T>
414                    where
415                        T: Trait,
416                    {
417                        foo: T,
418                    }
419
420                    impl<T> From<T> for Foo<T>
421                    where
422                        T: Trait,
423                    {
424                        fn from(foo: T) -> Self {
425                            Self { foo }
426                        }
427                    }
428                }
429            }
430            "#,
431        );
432        check_assist(
433            generate_single_field_struct_from,
434            r#"
435            //- minicore: from
436            mod foo {
437                mod bar {
438                    trait Trait<const B: bool> {}
439                    struct $0Foo<T>
440                    where
441                        T: Trait<{
442                            true
443                        }>
444                    {
445                        foo: T,
446                    }
447                }
448            }
449            "#,
450            r#"
451            mod foo {
452                mod bar {
453                    trait Trait<const B: bool> {}
454                    struct Foo<T>
455                    where
456                        T: Trait<{
457                            true
458                        }>
459                    {
460                        foo: T,
461                    }
462
463                    impl<T> From<T> for Foo<T>
464                    where
465                        T: Trait<{
466                            true
467                        }>
468                    {
469                        fn from(foo: T) -> Self {
470                            Self { foo }
471                        }
472                    }
473                }
474            }
475            "#,
476        );
477    }
478
479    #[test]
480    fn generics() {
481        check_assist(
482            generate_single_field_struct_from,
483            r#"
484            //- minicore: from
485            struct $0Foo<T> {
486                foo: T,
487            }
488            "#,
489            r#"
490            struct Foo<T> {
491                foo: T,
492            }
493
494            impl<T> From<T> for Foo<T> {
495                fn from(foo: T) -> Self {
496                    Self { foo }
497                }
498            }
499            "#,
500        );
501        check_assist(
502            generate_single_field_struct_from,
503            r#"
504            //- minicore: from
505            struct $0Foo<T: Send> {
506                foo: T,
507            }
508            "#,
509            r#"
510            struct Foo<T: Send> {
511                foo: T,
512            }
513
514            impl<T: Send> From<T> for Foo<T> {
515                fn from(foo: T) -> Self {
516                    Self { foo }
517                }
518            }
519            "#,
520        );
521        check_assist(
522            generate_single_field_struct_from,
523            r#"
524            //- minicore: from
525            struct $0Foo<T: Send> where T: Sync,{
526                foo: T,
527            }
528            "#,
529            r#"
530            struct Foo<T: Send> where T: Sync,{
531                foo: T,
532            }
533
534            impl<T: Send> From<T> for Foo<T>
535            where T: Sync,
536            {
537                fn from(foo: T) -> Self {
538                    Self { foo }
539                }
540            }
541            "#,
542        );
543        check_assist(
544            generate_single_field_struct_from,
545            r#"
546            //- minicore: from
547            struct $0Foo<T: Send> where T: Sync {
548                foo: T,
549            }
550            "#,
551            r#"
552            struct Foo<T: Send> where T: Sync {
553                foo: T,
554            }
555
556            impl<T: Send> From<T> for Foo<T>
557            where T: Sync
558            {
559                fn from(foo: T) -> Self {
560                    Self { foo }
561                }
562            }
563            "#,
564        );
565        check_assist(
566            generate_single_field_struct_from,
567            r#"
568            //- minicore: from
569            struct $0Foo<T: Send> where T: Sync, Self: Send {
570                foo: T,
571            }
572            "#,
573            r#"
574            struct Foo<T: Send> where T: Sync, Self: Send {
575                foo: T,
576            }
577
578            impl<T: Send> From<T> for Foo<T>
579            where T: Sync, Self: Send
580            {
581                fn from(foo: T) -> Self {
582                    Self { foo }
583                }
584            }
585            "#,
586        );
587        check_assist(
588            generate_single_field_struct_from,
589            r#"
590            //- minicore: from
591            struct $0Foo<T: Send>
592            where T: Sync, Self: Send
593            {
594                foo: T,
595            }
596            "#,
597            r#"
598            struct Foo<T: Send>
599            where T: Sync, Self: Send
600            {
601                foo: T,
602            }
603
604            impl<T: Send> From<T> for Foo<T>
605            where T: Sync, Self: Send
606            {
607                fn from(foo: T) -> Self {
608                    Self { foo }
609                }
610            }
611            "#,
612        );
613        check_assist(
614            generate_single_field_struct_from,
615            r#"
616            //- minicore: from
617            struct $0Foo<T: Send>
618            where T: Sync, Self: Send,
619            {
620                foo: T,
621            }
622            "#,
623            r#"
624            struct Foo<T: Send>
625            where T: Sync, Self: Send,
626            {
627                foo: T,
628            }
629
630            impl<T: Send> From<T> for Foo<T>
631            where T: Sync, Self: Send,
632            {
633                fn from(foo: T) -> Self {
634                    Self { foo }
635                }
636            }
637            "#,
638        );
639        check_assist(
640            generate_single_field_struct_from,
641            r#"
642            //- minicore: from
643            struct $0Foo<T: Send>
644            where T: Sync,
645                  Self: Send,
646            {
647                foo: T,
648            }
649            "#,
650            r#"
651            struct Foo<T: Send>
652            where T: Sync,
653                  Self: Send,
654            {
655                foo: T,
656            }
657
658            impl<T: Send> From<T> for Foo<T>
659            where T: Sync,
660                  Self: Send,
661            {
662                fn from(foo: T) -> Self {
663                    Self { foo }
664                }
665            }
666            "#,
667        );
668        check_assist(
669            generate_single_field_struct_from,
670            r#"
671            //- minicore: from
672            struct $0Foo<T: Send>
673            where
674                T: Sync,
675                Self: Send,
676            {
677                foo: T,
678            }
679            "#,
680            r#"
681            struct Foo<T: Send>
682            where
683                T: Sync,
684                Self: Send,
685            {
686                foo: T,
687            }
688
689            impl<T: Send> From<T> for Foo<T>
690            where
691                T: Sync,
692                Self: Send,
693            {
694                fn from(foo: T) -> Self {
695                    Self { foo }
696                }
697            }
698            "#,
699        );
700        check_assist(
701            generate_single_field_struct_from,
702            r#"
703            //- minicore: from
704            struct $0Foo<T: Send + Sync>
705            where
706                T: Sync,
707                Self: Send,
708            {
709                foo: T,
710            }
711            "#,
712            r#"
713            struct Foo<T: Send + Sync>
714            where
715                T: Sync,
716                Self: Send,
717            {
718                foo: T,
719            }
720
721            impl<T: Send + Sync> From<T> for Foo<T>
722            where
723                T: Sync,
724                Self: Send,
725            {
726                fn from(foo: T) -> Self {
727                    Self { foo }
728                }
729            }
730            "#,
731        );
732    }
733
734    #[test]
735    fn tuple() {
736        check_assist(
737            generate_single_field_struct_from,
738            r#"
739            //- minicore: from
740            struct $0Foo(i32);
741            "#,
742            r#"
743            struct Foo(i32);
744
745            impl From<i32> for Foo {
746                fn from(value: i32) -> Self {
747                    Self(value)
748                }
749            }
750            "#,
751        );
752        check_assist(
753            generate_single_field_struct_from,
754            r#"
755            //- minicore: from
756            struct $0Foo<T>(T);
757            "#,
758            r#"
759            struct Foo<T>(T);
760
761            impl<T> From<T> for Foo<T> {
762                fn from(value: T) -> Self {
763                    Self(value)
764                }
765            }
766            "#,
767        );
768    }
769
770    #[test]
771    fn trivial() {
772        check_assist(
773            generate_single_field_struct_from,
774            r#"
775            //- minicore: from, phantom_data
776            use core::marker::PhantomData;
777            struct $0Foo(i32, PhantomData<i32>);
778            "#,
779            r#"
780            use core::marker::PhantomData;
781            struct Foo(i32, PhantomData<i32>);
782
783            impl From<i32> for Foo {
784                fn from(value: i32) -> Self {
785                    Self(value, PhantomData)
786                }
787            }
788            "#,
789        );
790        check_assist(
791            generate_single_field_struct_from,
792            r#"
793            //- minicore: from, phantom_data
794            use core::marker::PhantomData;
795            struct $0Foo(i32, PhantomData<()>);
796            "#,
797            r#"
798            use core::marker::PhantomData;
799            struct Foo(i32, PhantomData<()>);
800
801            impl From<i32> for Foo {
802                fn from(value: i32) -> Self {
803                    Self(value, PhantomData)
804                }
805            }
806            "#,
807        );
808        check_assist(
809            generate_single_field_struct_from,
810            r#"
811            //- minicore: from, phantom_data
812            use core::marker::PhantomData;
813            struct $0Foo(PhantomData<()>, i32, PhantomData<()>);
814            "#,
815            r#"
816            use core::marker::PhantomData;
817            struct Foo(PhantomData<()>, i32, PhantomData<()>);
818
819            impl From<i32> for Foo {
820                fn from(value: i32) -> Self {
821                    Self(PhantomData, value, PhantomData)
822                }
823            }
824            "#,
825        );
826        check_assist(
827            generate_single_field_struct_from,
828            r#"
829            //- minicore: from, phantom_data
830            use core::marker::PhantomData;
831            struct $0Foo<T>(PhantomData<T>, i32, PhantomData<()>);
832            "#,
833            r#"
834            use core::marker::PhantomData;
835            struct Foo<T>(PhantomData<T>, i32, PhantomData<()>);
836
837            impl<T> From<i32> for Foo<T> {
838                fn from(value: i32) -> Self {
839                    Self(PhantomData, value, PhantomData)
840                }
841            }
842            "#,
843        );
844    }
845
846    #[test]
847    fn unit() {
848        check_assist(
849            generate_single_field_struct_from,
850            r#"
851            //- minicore: from
852            struct $0Foo(i32, ());
853            "#,
854            r#"
855            struct Foo(i32, ());
856
857            impl From<i32> for Foo {
858                fn from(value: i32) -> Self {
859                    Self(value, ())
860                }
861            }
862            "#,
863        );
864        check_assist(
865            generate_single_field_struct_from,
866            r#"
867            //- minicore: from
868            struct $0Foo((), i32, ());
869            "#,
870            r#"
871            struct Foo((), i32, ());
872
873            impl From<i32> for Foo {
874                fn from(value: i32) -> Self {
875                    Self((), value, ())
876                }
877            }
878            "#,
879        );
880        check_assist(
881            generate_single_field_struct_from,
882            r#"
883            //- minicore: from
884            struct $0Foo((), (), i32, ());
885            "#,
886            r#"
887            struct Foo((), (), i32, ());
888
889            impl From<i32> for Foo {
890                fn from(value: i32) -> Self {
891                    Self((), (), value, ())
892                }
893            }
894            "#,
895        );
896    }
897
898    #[test]
899    fn invalid_multiple_main_field() {
900        check_assist_not_applicable(
901            generate_single_field_struct_from,
902            r#"
903            //- minicore: from
904            struct $0Foo(i32, i32);
905            "#,
906        );
907        check_assist_not_applicable(
908            generate_single_field_struct_from,
909            r#"
910            //- minicore: from
911            struct $0Foo<T>(i32, T);
912            "#,
913        );
914        check_assist_not_applicable(
915            generate_single_field_struct_from,
916            r#"
917            //- minicore: from
918            struct $0Foo<T>(T, T);
919            "#,
920        );
921        check_assist_not_applicable(
922            generate_single_field_struct_from,
923            r#"
924            //- minicore: from
925            struct $0Foo<T> { foo: T, bar: i32 }
926            "#,
927        );
928        check_assist_not_applicable(
929            generate_single_field_struct_from,
930            r#"
931            //- minicore: from
932            struct $0Foo { foo: i32, bar: i64 }
933            "#,
934        );
935    }
936
937    #[test]
938    fn exists_other_from() {
939        check_assist(
940            generate_single_field_struct_from,
941            r#"
942            //- minicore: from
943            struct $0Foo(i32);
944
945            impl From<&i32> for Foo {
946                fn from(value: &i32) -> Self {
947                    todo!()
948                }
949            }
950            "#,
951            r#"
952            struct Foo(i32);
953
954            impl From<i32> for Foo {
955                fn from(value: i32) -> Self {
956                    Self(value)
957                }
958            }
959
960            impl From<&i32> for Foo {
961                fn from(value: &i32) -> Self {
962                    todo!()
963                }
964            }
965            "#,
966        );
967        check_assist(
968            generate_single_field_struct_from,
969            r#"
970            //- minicore: from
971            struct $0Foo(i32);
972
973            type X = i32;
974
975            impl From<&X> for Foo {
976                fn from(value: &X) -> Self {
977                    todo!()
978                }
979            }
980            "#,
981            r#"
982            struct Foo(i32);
983
984            impl From<i32> for Foo {
985                fn from(value: i32) -> Self {
986                    Self(value)
987                }
988            }
989
990            type X = i32;
991
992            impl From<&X> for Foo {
993                fn from(value: &X) -> Self {
994                    todo!()
995                }
996            }
997            "#,
998        );
999    }
1000
1001    #[test]
1002    fn exists_from() {
1003        check_assist_not_applicable(
1004            generate_single_field_struct_from,
1005            r#"
1006            //- minicore: from
1007            struct $0Foo(i32);
1008
1009            impl From<i32> for Foo {
1010                fn from(_: i32) -> Self {
1011                    todo!()
1012                }
1013            }
1014            "#,
1015        );
1016        check_assist_not_applicable(
1017            generate_single_field_struct_from,
1018            r#"
1019            //- minicore: from
1020            struct $0Foo(i32);
1021
1022            type X = i32;
1023
1024            impl From<X> for Foo {
1025                fn from(_: X) -> Self {
1026                    todo!()
1027                }
1028            }
1029            "#,
1030        );
1031    }
1032}