Skip to content

Commit ac03de7

Browse files
committed
Add flag to disallow opaque types for DisplayTarget::SourceCode
1 parent 7501d3b commit ac03de7

File tree

15 files changed

+62
-29
lines changed

15 files changed

+62
-29
lines changed

crates/hir-ty/src/display.rs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ pub trait HirDisplay {
150150
&'a self,
151151
db: &'a dyn HirDatabase,
152152
module_id: ModuleId,
153+
allow_opaque: bool,
153154
) -> Result<String, DisplaySourceCodeError> {
154155
let mut result = String::new();
155156
match self.hir_fmt(&mut HirFormatter {
@@ -160,7 +161,7 @@ pub trait HirDisplay {
160161
max_size: None,
161162
omit_verbose_types: false,
162163
closure_style: ClosureStyle::ImplFn,
163-
display_target: DisplayTarget::SourceCode { module_id },
164+
display_target: DisplayTarget::SourceCode { module_id, allow_opaque },
164165
}) {
165166
Ok(()) => {}
166167
Err(HirDisplayError::FmtError) => panic!("Writing to String can't fail!"),
@@ -249,25 +250,34 @@ pub enum DisplayTarget {
249250
Diagnostics,
250251
/// Display types for inserting them in source files.
251252
/// The generated code should compile, so paths need to be qualified.
252-
SourceCode { module_id: ModuleId },
253+
SourceCode { module_id: ModuleId, allow_opaque: bool },
253254
/// Only for test purpose to keep real types
254255
Test,
255256
}
256257

257258
impl DisplayTarget {
258-
fn is_source_code(&self) -> bool {
259+
fn is_source_code(self) -> bool {
259260
matches!(self, Self::SourceCode { .. })
260261
}
261-
fn is_test(&self) -> bool {
262+
263+
fn is_test(self) -> bool {
262264
matches!(self, Self::Test)
263265
}
266+
267+
fn allows_opaque(self) -> bool {
268+
match self {
269+
Self::SourceCode { allow_opaque, .. } => allow_opaque,
270+
_ => true,
271+
}
272+
}
264273
}
265274

266275
#[derive(Debug)]
267276
pub enum DisplaySourceCodeError {
268277
PathNotFound,
269278
UnknownType,
270279
Generator,
280+
OpaqueType,
271281
}
272282

273283
pub enum HirDisplayError {
@@ -768,7 +778,7 @@ impl HirDisplay for Ty {
768778
};
769779
write!(f, "{name}")?;
770780
}
771-
DisplayTarget::SourceCode { module_id } => {
781+
DisplayTarget::SourceCode { module_id, allow_opaque: _ } => {
772782
if let Some(path) = find_path::find_path(
773783
db.upcast(),
774784
ItemInNs::Types((*def_id).into()),
@@ -906,6 +916,11 @@ impl HirDisplay for Ty {
906916
f.end_location_link();
907917
}
908918
TyKind::OpaqueType(opaque_ty_id, parameters) => {
919+
if !f.display_target.allows_opaque() {
920+
return Err(HirDisplayError::DisplaySourceCodeError(
921+
DisplaySourceCodeError::OpaqueType,
922+
));
923+
}
909924
let impl_trait_id = db.lookup_intern_impl_trait_id((*opaque_ty_id).into());
910925
match impl_trait_id {
911926
ImplTraitId::ReturnTypeImplTrait(func, idx) => {
@@ -953,8 +968,14 @@ impl HirDisplay for Ty {
953968
}
954969
}
955970
TyKind::Closure(id, substs) => {
956-
if f.display_target.is_source_code() && f.closure_style != ClosureStyle::ImplFn {
957-
never!("Only `impl Fn` is valid for displaying closures in source code");
971+
if f.display_target.is_source_code() {
972+
if !f.display_target.allows_opaque() {
973+
return Err(HirDisplayError::DisplaySourceCodeError(
974+
DisplaySourceCodeError::OpaqueType,
975+
));
976+
} else if f.closure_style != ClosureStyle::ImplFn {
977+
never!("Only `impl Fn` is valid for displaying closures in source code");
978+
}
958979
}
959980
match f.closure_style {
960981
ClosureStyle::Hide => return write!(f, "{TYPE_HINT_TRUNCATION}"),
@@ -1053,6 +1074,11 @@ impl HirDisplay for Ty {
10531074
}
10541075
TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
10551076
TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
1077+
if !f.display_target.allows_opaque() {
1078+
return Err(HirDisplayError::DisplaySourceCodeError(
1079+
DisplaySourceCodeError::OpaqueType,
1080+
));
1081+
}
10561082
let impl_trait_id = db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into());
10571083
match impl_trait_id {
10581084
ImplTraitId::ReturnTypeImplTrait(func, idx) => {

crates/hir-ty/src/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
159159
let range = node.as_ref().original_file_range(&db);
160160
if let Some(expected) = types.remove(&range) {
161161
let actual = if display_source {
162-
ty.display_source_code(&db, def.module(&db)).unwrap()
162+
ty.display_source_code(&db, def.module(&db), true).unwrap()
163163
} else {
164164
ty.display_test(&db).to_string()
165165
};
@@ -175,7 +175,7 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
175175
let range = node.as_ref().original_file_range(&db);
176176
if let Some(expected) = types.remove(&range) {
177177
let actual = if display_source {
178-
ty.display_source_code(&db, def.module(&db)).unwrap()
178+
ty.display_source_code(&db, def.module(&db), true).unwrap()
179179
} else {
180180
ty.display_test(&db).to_string()
181181
};

crates/ide-assists/src/handlers/add_explicit_type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
6969
return None;
7070
}
7171

72-
let inferred_type = ty.display_source_code(ctx.db(), module.into()).ok()?;
72+
let inferred_type = ty.display_source_code(ctx.db(), module.into(), false).ok()?;
7373
acc.add(
7474
AssistId("add_explicit_type", AssistKind::RefactorRewrite),
7575
format!("Insert explicit type `{inferred_type}`"),

crates/ide-assists/src/handlers/add_return_type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub(crate) fn add_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
2222
if ty.is_unit() {
2323
return None;
2424
}
25-
let ty = ty.display_source_code(ctx.db(), module.into()).ok()?;
25+
let ty = ty.display_source_code(ctx.db(), module.into(), true).ok()?;
2626

2727
acc.add(
2828
AssistId("add_return_type", AssistKind::RefactorRewrite),

crates/ide-assists/src/handlers/extract_function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1884,7 +1884,7 @@ fn with_tail_expr(block: ast::BlockExpr, tail_expr: ast::Expr) -> ast::BlockExpr
18841884
}
18851885

18861886
fn format_type(ty: &hir::Type, ctx: &AssistContext<'_>, module: hir::Module) -> String {
1887-
ty.display_source_code(ctx.db(), module.into()).ok().unwrap_or_else(|| "_".to_string())
1887+
ty.display_source_code(ctx.db(), module.into(), true).ok().unwrap_or_else(|| "_".to_string())
18881888
}
18891889

18901890
fn make_ty(ty: &hir::Type, ctx: &AssistContext<'_>, module: hir::Module) -> ast::Type {

crates/ide-assists/src/handlers/generate_constant.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ pub(crate) fn generate_constant(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
4646
let ty = ctx.sema.type_of_expr(&expr)?;
4747
let scope = ctx.sema.scope(statement.syntax())?;
4848
let constant_module = scope.module();
49-
let type_name = ty.original().display_source_code(ctx.db(), constant_module.into()).ok()?;
49+
let type_name =
50+
ty.original().display_source_code(ctx.db(), constant_module.into(), false).ok()?;
5051
let target = statement.syntax().parent()?.text_range();
5152
let path = constant_token.syntax().ancestors().find_map(ast::Path::cast)?;
5253

crates/ide-assists/src/handlers/generate_enum_variant.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ fn expr_ty(
192192
scope: &hir::SemanticsScope<'_>,
193193
) -> Option<ast::Type> {
194194
let ty = ctx.sema.type_of_expr(&arg).map(|it| it.adjusted())?;
195-
let text = ty.display_source_code(ctx.db(), scope.module().into()).ok()?;
195+
let text = ty.display_source_code(ctx.db(), scope.module().into(), false).ok()?;
196196
Some(make::ty(&text))
197197
}
198198

crates/ide-assists/src/handlers/generate_function.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ fn make_return_type(
438438
Some(ty) if ty.is_unit() => (None, false),
439439
Some(ty) => {
440440
necessary_generic_params.extend(ty.generic_params(ctx.db()));
441-
let rendered = ty.display_source_code(ctx.db(), target_module.into());
441+
let rendered = ty.display_source_code(ctx.db(), target_module.into(), true);
442442
match rendered {
443443
Ok(rendered) => (Some(make::ty(&rendered)), false),
444444
Err(_) => (Some(make::ty_placeholder()), true),
@@ -992,9 +992,9 @@ fn fn_arg_type(
992992
let famous_defs = &FamousDefs(&ctx.sema, ctx.sema.scope(fn_arg.syntax())?.krate());
993993
convert_reference_type(ty.strip_references(), ctx.db(), famous_defs)
994994
.map(|conversion| conversion.convert_type(ctx.db()))
995-
.or_else(|| ty.display_source_code(ctx.db(), target_module.into()).ok())
995+
.or_else(|| ty.display_source_code(ctx.db(), target_module.into(), true).ok())
996996
} else {
997-
ty.display_source_code(ctx.db(), target_module.into()).ok()
997+
ty.display_source_code(ctx.db(), target_module.into(), true).ok()
998998
}
999999
}
10001000

crates/ide-assists/src/handlers/promote_local_to_const.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,13 @@ pub(crate) fn promote_local_to_const(acc: &mut Assists, ctx: &AssistContext<'_>)
5757
let local = ctx.sema.to_def(&pat)?;
5858
let ty = ctx.sema.type_of_pat(&pat.into())?.original;
5959

60-
if ty.contains_unknown() || ty.is_closure() {
61-
cov_mark::hit!(promote_lcoal_not_applicable_if_ty_not_inferred);
62-
return None;
63-
}
64-
let ty = ty.display_source_code(ctx.db(), module.into()).ok()?;
60+
let ty = match ty.display_source_code(ctx.db(), module.into(), false) {
61+
Ok(ty) => ty,
62+
Err(_) => {
63+
cov_mark::hit!(promote_local_not_applicable_if_ty_not_inferred);
64+
return None;
65+
}
66+
};
6567

6668
let initializer = let_stmt.initializer()?;
6769
if !is_body_const(&ctx.sema, &initializer) {
@@ -187,7 +189,7 @@ fn foo() {
187189

188190
#[test]
189191
fn not_applicable_unknown_ty() {
190-
cov_mark::check!(promote_lcoal_not_applicable_if_ty_not_inferred);
192+
cov_mark::check!(promote_local_not_applicable_if_ty_not_inferred);
191193
check_assist_not_applicable(
192194
promote_local_to_const,
193195
r"

crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub(crate) fn replace_turbofish_with_explicit_type(
5555
let returned_type = match ctx.sema.type_of_expr(&initializer) {
5656
Some(returned_type) if !returned_type.original.contains_unknown() => {
5757
let module = ctx.sema.scope(let_stmt.syntax())?.module();
58-
returned_type.original.display_source_code(ctx.db(), module.into()).ok()?
58+
returned_type.original.display_source_code(ctx.db(), module.into(), false).ok()?
5959
}
6060
_ => {
6161
cov_mark::hit!(fallback_to_turbofish_type_if_type_info_not_available);

0 commit comments

Comments
 (0)