diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 6c7489e63ba..486314cc524 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -723,8 +723,7 @@ impl ExprCollector {
 
                 let lit = match child.flavor() {
                     LiteralFlavor::IntNumber { suffix } => {
-                        let known_name =
-                            suffix.map(Name::new).and_then(|name| UncertainIntTy::from_name(&name));
+                        let known_name = suffix.and_then(|it| UncertainIntTy::from_suffix(&it));
 
                         Literal::Int(
                             Default::default(),
@@ -732,9 +731,7 @@ impl ExprCollector {
                         )
                     }
                     LiteralFlavor::FloatNumber { suffix } => {
-                        let known_name = suffix
-                            .map(Name::new)
-                            .and_then(|name| UncertainFloatTy::from_name(&name));
+                        let known_name = suffix.and_then(|it| UncertainFloatTy::from_suffix(&it));
 
                         Literal::Float(
                             Default::default(),
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs
index 06bafa6f068..677d18efccc 100644
--- a/crates/ra_hir/src/name.rs
+++ b/crates/ra_hir/src/name.rs
@@ -23,7 +23,10 @@ impl fmt::Debug for Name {
 }
 
 impl Name {
-    pub(crate) fn new(text: SmolStr) -> Name {
+    /// Note: this is private to make creating name from random string hard.
+    /// Hopefully, this should allow us to integrate hygiene cleaner in the
+    /// future, and to switch to interned representation of names.
+    fn new(text: SmolStr) -> Name {
         Name { text }
     }
 
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 278f592d391..389a2fc68a5 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -63,9 +63,9 @@ impl Ty {
     pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self {
         if let Some(name) = path.as_ident() {
             // TODO handle primitive type names in resolver as well?
-            if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) {
+            if let Some(int_ty) = primitive::UncertainIntTy::from_type_name(name) {
                 return Ty::Int(int_ty);
-            } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) {
+            } else if let Some(float_ty) = primitive::UncertainFloatTy::from_type_name(name) {
                 return Ty::Float(float_ty);
             } else if let Some(known) = name.as_known_name() {
                 match known {
diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs
index 30aeac48e6f..421f7e980d4 100644
--- a/crates/ra_hir/src/ty/primitive.rs
+++ b/crates/ra_hir/src/ty/primitive.rs
@@ -10,10 +10,20 @@ pub enum UncertainIntTy {
 }
 
 impl UncertainIntTy {
-    pub fn from_name(name: &Name) -> Option<UncertainIntTy> {
-        if let Some(ty) = IntTy::from_name(name) {
+    pub(crate) fn from_type_name(name: &Name) -> Option<UncertainIntTy> {
+        if let Some(ty) = IntTy::from_type_name(name) {
             Some(UncertainIntTy::Signed(ty))
-        } else if let Some(ty) = UintTy::from_name(name) {
+        } else if let Some(ty) = UintTy::from_type_name(name) {
+            Some(UncertainIntTy::Unsigned(ty))
+        } else {
+            None
+        }
+    }
+
+    pub(crate) fn from_suffix(suffix: &str) -> Option<UncertainIntTy> {
+        if let Some(ty) = IntTy::from_suffix(suffix) {
+            Some(UncertainIntTy::Signed(ty))
+        } else if let Some(ty) = UintTy::from_suffix(suffix) {
             Some(UncertainIntTy::Unsigned(ty))
         } else {
             None
@@ -38,12 +48,12 @@ pub enum UncertainFloatTy {
 }
 
 impl UncertainFloatTy {
-    pub fn from_name(name: &Name) -> Option<UncertainFloatTy> {
-        if let Some(ty) = FloatTy::from_name(name) {
-            Some(UncertainFloatTy::Known(ty))
-        } else {
-            None
-        }
+    pub(crate) fn from_type_name(name: &Name) -> Option<UncertainFloatTy> {
+        FloatTy::from_type_name(name).map(UncertainFloatTy::Known)
+    }
+
+    pub(crate) fn from_suffix(suffix: &str) -> Option<UncertainFloatTy> {
+        FloatTy::from_suffix(suffix).map(UncertainFloatTy::Known)
     }
 }
 
@@ -87,7 +97,7 @@ impl fmt::Display for IntTy {
 }
 
 impl IntTy {
-    pub fn from_name(name: &Name) -> Option<IntTy> {
+    fn from_type_name(name: &Name) -> Option<IntTy> {
         match name.as_known_name()? {
             KnownName::Isize => Some(IntTy::Isize),
             KnownName::I8 => Some(IntTy::I8),
@@ -98,6 +108,18 @@ impl IntTy {
             _ => None,
         }
     }
+
+    fn from_suffix(suffix: &str) -> Option<IntTy> {
+        match suffix {
+            "isize" => Some(IntTy::Isize),
+            "i8" => Some(IntTy::I8),
+            "i16" => Some(IntTy::I16),
+            "i32" => Some(IntTy::I32),
+            "i64" => Some(IntTy::I64),
+            "i128" => Some(IntTy::I128),
+            _ => None,
+        }
+    }
 }
 
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
@@ -125,7 +147,7 @@ impl fmt::Display for UintTy {
 }
 
 impl UintTy {
-    pub fn from_name(name: &Name) -> Option<UintTy> {
+    fn from_type_name(name: &Name) -> Option<UintTy> {
         match name.as_known_name()? {
             KnownName::Usize => Some(UintTy::Usize),
             KnownName::U8 => Some(UintTy::U8),
@@ -136,6 +158,18 @@ impl UintTy {
             _ => None,
         }
     }
+
+    fn from_suffix(suffix: &str) -> Option<UintTy> {
+        match suffix {
+            "usize" => Some(UintTy::Usize),
+            "u8" => Some(UintTy::U8),
+            "u16" => Some(UintTy::U16),
+            "u32" => Some(UintTy::U32),
+            "u64" => Some(UintTy::U64),
+            "u128" => Some(UintTy::U128),
+            _ => None,
+        }
+    }
 }
 
 impl fmt::Debug for UintTy {
@@ -170,11 +204,19 @@ impl FloatTy {
         }
     }
 
-    pub fn from_name(name: &Name) -> Option<FloatTy> {
+    fn from_type_name(name: &Name) -> Option<FloatTy> {
         match name.as_known_name()? {
             KnownName::F32 => Some(FloatTy::F32),
             KnownName::F64 => Some(FloatTy::F64),
             _ => None,
         }
     }
+
+    fn from_suffix(suffix: &str) -> Option<FloatTy> {
+        match suffix {
+            "f32" => Some(FloatTy::F32),
+            "f64" => Some(FloatTy::F64),
+            _ => None,
+        }
+    }
 }