Skip to content

Commit 4791a5d

Browse files
committed
Auto merge of #15692 - Veykril:underscore-completions, r=Veykril
fix: Typing underscore should not trigger completions in types or patterns
2 parents 547bcf8 + ae5d74d commit 4791a5d

File tree

2 files changed

+131
-0
lines changed

2 files changed

+131
-0
lines changed

crates/ide-completion/src/lib.rs

+22
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,28 @@ pub fn completions(
169169
return Some(completions.into());
170170
}
171171

172+
// when the user types a bare `_` (that is it does not belong to an identifier)
173+
// the user might just wanted to type a `_` for type inference or pattern discarding
174+
// so try to suppress completions in those cases
175+
if trigger_character == Some('_') && ctx.original_token.kind() == syntax::SyntaxKind::UNDERSCORE
176+
{
177+
if let CompletionAnalysis::NameRef(NameRefContext {
178+
kind:
179+
NameRefKind::Path(
180+
path_ctx @ PathCompletionCtx {
181+
kind: PathKind::Type { .. } | PathKind::Pat { .. },
182+
..
183+
},
184+
),
185+
..
186+
}) = analysis
187+
{
188+
if path_ctx.is_trivial_path() {
189+
return None;
190+
}
191+
}
192+
}
193+
172194
{
173195
let acc = &mut completions;
174196

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

+109
Original file line numberDiff line numberDiff line change
@@ -1372,3 +1372,112 @@ fn main() {
13721372
expect!("pub const fn baz<'foo>(&'foo mut self, x: &'foo Foo) -> !"),
13731373
);
13741374
}
1375+
1376+
#[test]
1377+
fn skips_underscore() {
1378+
check_with_trigger_character(
1379+
r#"
1380+
fn foo(_$0) { }
1381+
"#,
1382+
Some('_'),
1383+
expect![[r#""#]],
1384+
);
1385+
check_with_trigger_character(
1386+
r#"
1387+
fn foo(_: _$0) { }
1388+
"#,
1389+
Some('_'),
1390+
expect![[r#""#]],
1391+
);
1392+
check_with_trigger_character(
1393+
r#"
1394+
fn foo<T>() {
1395+
foo::<_$0>();
1396+
}
1397+
"#,
1398+
Some('_'),
1399+
expect![[r#""#]],
1400+
);
1401+
// underscore expressions are fine, they are invalid so the user definitely meant to type an
1402+
// underscored name here
1403+
check_with_trigger_character(
1404+
r#"
1405+
fn foo() {
1406+
_$0
1407+
}
1408+
"#,
1409+
Some('_'),
1410+
expect![[r#"
1411+
fn foo() fn()
1412+
bt u32
1413+
kw const
1414+
kw crate::
1415+
kw enum
1416+
kw extern
1417+
kw false
1418+
kw fn
1419+
kw for
1420+
kw if
1421+
kw if let
1422+
kw impl
1423+
kw let
1424+
kw loop
1425+
kw match
1426+
kw mod
1427+
kw return
1428+
kw self::
1429+
kw static
1430+
kw struct
1431+
kw trait
1432+
kw true
1433+
kw type
1434+
kw union
1435+
kw unsafe
1436+
kw use
1437+
kw while
1438+
kw while let
1439+
sn macro_rules
1440+
sn pd
1441+
sn ppd
1442+
"#]],
1443+
);
1444+
}
1445+
1446+
#[test]
1447+
fn no_skip_underscore_ident() {
1448+
check_with_trigger_character(
1449+
r#"
1450+
fn foo(a_$0) { }
1451+
"#,
1452+
Some('_'),
1453+
expect![[r#"
1454+
kw mut
1455+
kw ref
1456+
"#]],
1457+
);
1458+
check_with_trigger_character(
1459+
r#"
1460+
fn foo(_: a_$0) { }
1461+
"#,
1462+
Some('_'),
1463+
expect![[r#"
1464+
bt u32
1465+
kw crate::
1466+
kw self::
1467+
"#]],
1468+
);
1469+
check_with_trigger_character(
1470+
r#"
1471+
fn foo<T>() {
1472+
foo::<a_$0>();
1473+
}
1474+
"#,
1475+
Some('_'),
1476+
expect![[r#"
1477+
tp T
1478+
bt u32
1479+
kw crate::
1480+
kw self::
1481+
"#]],
1482+
);
1483+
}

0 commit comments

Comments
 (0)