diff --git a/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs b/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
index 03806724a3a..49deb670175 100644
--- a/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
+++ b/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
@@ -1,11 +1,12 @@
+use ra_ide_db::RootDatabase;
 use ra_syntax::{
     ast::{self, AstNode, NameOwner},
     TextSize,
 };
 use stdx::format_to;
 
-use crate::{Assist, AssistCtx, AssistId};
-use ra_ide_db::RootDatabase;
+use crate::{utils::FamousDefs, Assist, AssistCtx, AssistId};
+use test_utils::tested_by;
 
 // Assist add_from_impl_for_enum
 //
@@ -41,7 +42,8 @@ pub(crate) fn add_from_impl_for_enum(ctx: AssistCtx) -> Option<Assist> {
         _ => return None,
     };
 
-    if already_has_from_impl(ctx.sema, &variant) {
+    if existing_from_impl(ctx.sema, &variant).is_some() {
+        tested_by!(test_add_from_impl_already_exists);
         return None;
     }
 
@@ -70,41 +72,33 @@ impl From<{0}> for {1} {{
     )
 }
 
-fn already_has_from_impl(
+fn existing_from_impl(
     sema: &'_ hir::Semantics<'_, RootDatabase>,
     variant: &ast::EnumVariant,
-) -> bool {
-    let scope = sema.scope(&variant.syntax());
+) -> Option<()> {
+    let variant = sema.to_def(variant)?;
+    let enum_ = variant.parent_enum(sema.db);
+    let krate = enum_.module(sema.db).krate();
 
-    let from_path = ast::make::path_from_text("From");
-    let from_hir_path = match hir::Path::from_ast(from_path) {
-        Some(p) => p,
-        None => return false,
-    };
-    let from_trait = match scope.resolve_hir_path(&from_hir_path) {
-        Some(hir::PathResolution::Def(hir::ModuleDef::Trait(t))) => t,
-        _ => return false,
-    };
+    let from_trait = FamousDefs(sema, krate).core_convert_From()?;
 
-    let e: hir::Enum = match sema.to_def(&variant.parent_enum()) {
-        Some(e) => e,
-        None => return false,
-    };
-    let e_ty = e.ty(sema.db);
+    let enum_type = enum_.ty(sema.db);
 
-    let hir_enum_var: hir::EnumVariant = match sema.to_def(variant) {
-        Some(ev) => ev,
-        None => return false,
-    };
-    let var_ty = hir_enum_var.fields(sema.db)[0].signature_ty(sema.db);
+    let wrapped_type = variant.fields(sema.db).get(0)?.signature_ty(sema.db);
 
-    e_ty.impls_trait(sema.db, from_trait, &[var_ty])
+    if enum_type.impls_trait(sema.db, from_trait, &[wrapped_type]) {
+        Some(())
+    } else {
+        None
+    }
 }
 
 #[cfg(test)]
 mod tests {
     use super::*;
+
     use crate::helpers::{check_assist, check_assist_not_applicable};
+    use test_utils::covers;
 
     #[test]
     fn test_add_from_impl_for_enum() {
@@ -136,36 +130,40 @@ mod tests {
         );
     }
 
+    fn check_not_applicable(ra_fixture: &str) {
+        let fixture =
+            format!("//- main.rs crate:main deps:core\n{}\n{}", ra_fixture, FamousDefs::FIXTURE);
+        check_assist_not_applicable(add_from_impl_for_enum, &fixture)
+    }
+
     #[test]
     fn test_add_from_impl_no_element() {
-        check_assist_not_applicable(add_from_impl_for_enum, "enum A { <|>One }");
+        check_not_applicable("enum A { <|>One }");
     }
 
     #[test]
     fn test_add_from_impl_more_than_one_element_in_tuple() {
-        check_assist_not_applicable(add_from_impl_for_enum, "enum A { <|>One(u32, String) }");
+        check_not_applicable("enum A { <|>One(u32, String) }");
     }
 
     #[test]
     fn test_add_from_impl_struct_variant() {
-        check_assist_not_applicable(add_from_impl_for_enum, "enum A { <|>One { x: u32 } }");
+        check_not_applicable("enum A { <|>One { x: u32 } }");
     }
 
     #[test]
     fn test_add_from_impl_already_exists() {
-        check_assist_not_applicable(
-            add_from_impl_for_enum,
-            r#"enum A { <|>One(u32), }
+        covers!(test_add_from_impl_already_exists);
+        check_not_applicable(
+            r#"
+enum A { <|>One(u32), }
 
 impl From<u32> for A {
     fn from(v: u32) -> Self {
         A::One(v)
     }
 }
-
-pub trait From<T> {
-    fn from(T) -> Self;
-}"#,
+"#,
         );
     }
 
diff --git a/crates/ra_assists/src/marks.rs b/crates/ra_assists/src/marks.rs
index 6c2a2b8b6ea..8d910205f0a 100644
--- a/crates/ra_assists/src/marks.rs
+++ b/crates/ra_assists/src/marks.rs
@@ -8,4 +8,5 @@ test_utils::marks![
     test_not_inline_mut_variable
     test_not_applicable_if_variable_unused
     change_visibility_field_false_positive
+    test_add_from_impl_already_exists
 ];
diff --git a/crates/ra_assists/src/utils.rs b/crates/ra_assists/src/utils.rs
index 61f8bd1dcac..efd9886978a 100644
--- a/crates/ra_assists/src/utils.rs
+++ b/crates/ra_assists/src/utils.rs
@@ -3,7 +3,7 @@ pub(crate) mod insert_use;
 
 use std::iter;
 
-use hir::{Adt, Semantics, Type};
+use hir::{Adt, Crate, Semantics, Trait, Type};
 use ra_ide_db::RootDatabase;
 use ra_syntax::{
     ast::{self, make, NameOwner},
@@ -149,3 +149,61 @@ impl TryEnum {
         }
     }
 }
+
+/// Helps with finding well-know things inside the standard library. This is
+/// somewhat similar to the known paths infra inside hir, but it different; We
+/// want to make sure that IDE specific paths don't become interesting inside
+/// the compiler itself as well.
+pub(crate) struct FamousDefs<'a, 'b>(pub(crate) &'a Semantics<'b, RootDatabase>, pub(crate) Crate);
+
+#[allow(non_snake_case)]
+impl FamousDefs<'_, '_> {
+    #[cfg(test)]
+    pub(crate) const FIXTURE: &'static str = r#"
+//- /libcore.rs crate:core
+pub mod convert{
+    pub trait From<T> {
+        fn from(T) -> Self;
+    }
+}
+
+pub mod prelude { pub use crate::convert::From }
+#[prelude_import]
+pub use prelude::*;
+"#;
+
+    pub(crate) fn core_convert_From(&self) -> Option<Trait> {
+        self.find_trait("core:convert:From")
+    }
+
+    fn find_trait(&self, path: &str) -> Option<Trait> {
+        let db = self.0.db;
+        let mut path = path.split(':');
+        let trait_ = path.next_back()?;
+        let std_crate = path.next()?;
+        let std_crate = self
+            .1
+            .dependencies(db)
+            .into_iter()
+            .find(|dep| &dep.name.to_string() == std_crate)?
+            .krate;
+
+        let mut module = std_crate.root_module(db)?;
+        for segment in path {
+            module = module.children(db).find_map(|child| {
+                let name = child.name(db)?;
+                if &name.to_string() == segment {
+                    Some(child)
+                } else {
+                    None
+                }
+            })?;
+        }
+        let def =
+            module.scope(db, None).into_iter().find(|(name, _def)| &name.to_string() == trait_)?.1;
+        match def {
+            hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
+            _ => None,
+        }
+    }
+}
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs
index ee0f5cc406a..49208835325 100644
--- a/crates/ra_syntax/src/ast/make.rs
+++ b/crates/ra_syntax/src/ast/make.rs
@@ -22,8 +22,7 @@ pub fn path_unqualified(segment: ast::PathSegment) -> ast::Path {
 pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path {
     path_from_text(&format!("{}::{}", qual, segment))
 }
-
-pub fn path_from_text(text: &str) -> ast::Path {
+fn path_from_text(text: &str) -> ast::Path {
     ast_from_text(text)
 }