Skip to content

Commit 5b852da

Browse files
authored
Merge pull request #20110 from ChayimFriedman2/ambiguous-float
fix: Fix completion in when typing `integer.|`
2 parents a6c1fa0 + 0b6df17 commit 5b852da

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

crates/hir/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3046,10 +3046,17 @@ pub struct BuiltinType {
30463046
}
30473047

30483048
impl BuiltinType {
3049+
// Constructors are added on demand, feel free to add more.
30493050
pub fn str() -> BuiltinType {
30503051
BuiltinType { inner: hir_def::builtin_type::BuiltinType::Str }
30513052
}
30523053

3054+
pub fn i32() -> BuiltinType {
3055+
BuiltinType {
3056+
inner: hir_def::builtin_type::BuiltinType::Int(hir_ty::primitive::BuiltinInt::I32),
3057+
}
3058+
}
3059+
30533060
pub fn ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> {
30543061
let core = Crate::core(db).map(|core| core.id).unwrap_or_else(|| db.all_crates()[0]);
30553062
Type::new_for_crate(core, TyBuilder::builtin(self.inner))

crates/ide-completion/src/context/analysis.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::iter;
44
use hir::{ExpandResult, InFile, Semantics, Type, TypeInfo, Variant};
55
use ide_db::{RootDatabase, active_parameter::ActiveParameter};
66
use itertools::Either;
7+
use stdx::always;
78
use syntax::{
89
AstNode, AstToken, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken,
910
T, TextRange, TextSize,
@@ -869,8 +870,15 @@ fn classify_name_ref<'db>(
869870
return None;
870871
}
871872

873+
let mut receiver_ty = receiver.as_ref().and_then(|it| sema.type_of_expr(it));
874+
if receiver_is_ambiguous_float_literal {
875+
// `123.|` is parsed as a float but should actually be an integer.
876+
always!(receiver_ty.as_ref().is_none_or(|receiver_ty| receiver_ty.original.is_float()));
877+
receiver_ty = Some(TypeInfo { original: hir::BuiltinType::i32().ty(sema.db), adjusted: None });
878+
}
879+
872880
let kind = NameRefKind::DotAccess(DotAccess {
873-
receiver_ty: receiver.as_ref().and_then(|it| sema.type_of_expr(it)),
881+
receiver_ty,
874882
kind: DotAccessKind::Field { receiver_is_ambiguous_float_literal },
875883
receiver,
876884
ctx: DotAccessExprCtx { in_block_expr: is_in_block(field.syntax()), in_breakable: is_in_breakable(field.syntax()) }

crates/ide-completion/src/tests/expression.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,3 +2241,37 @@ fn main() {
22412241
"#,
22422242
);
22432243
}
2244+
2245+
#[test]
2246+
fn ambiguous_float_literal() {
2247+
check(
2248+
r#"
2249+
#![rustc_coherence_is_core]
2250+
2251+
impl i32 {
2252+
pub fn int_method(self) {}
2253+
}
2254+
impl f64 {
2255+
pub fn float_method(self) {}
2256+
}
2257+
2258+
fn foo() {
2259+
1.$0
2260+
}
2261+
"#,
2262+
expect![[r#"
2263+
me int_method() fn(self)
2264+
sn box Box::new(expr)
2265+
sn call function(expr)
2266+
sn const const {}
2267+
sn dbg dbg!(expr)
2268+
sn dbgr dbg!(&expr)
2269+
sn deref *expr
2270+
sn match match expr {}
2271+
sn ref &expr
2272+
sn refm &mut expr
2273+
sn return return expr
2274+
sn unsafe unsafe {}
2275+
"#]],
2276+
);
2277+
}

0 commit comments

Comments
 (0)