diff options
Diffstat (limited to 'crates/hir_ty/src/display.rs')
-rw-r--r-- | crates/hir_ty/src/display.rs | 299 |
1 files changed, 174 insertions, 125 deletions
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 51480304b..e0ca96c6d 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -1,14 +1,17 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use std::{array, fmt}; | 3 | use std::{ |
4 | array, | ||
5 | fmt::{self, Debug}, | ||
6 | }; | ||
4 | 7 | ||
5 | use chalk_ir::Mutability; | 8 | use chalk_ir::BoundVar; |
6 | use hir_def::{ | 9 | use hir_def::{ |
7 | db::DefDatabase, | 10 | db::DefDatabase, |
8 | find_path, | 11 | find_path, |
9 | generics::TypeParamProvenance, | 12 | generics::TypeParamProvenance, |
10 | item_scope::ItemInNs, | 13 | item_scope::ItemInNs, |
11 | path::{GenericArg, Path, PathKind}, | 14 | path::{Path, PathKind}, |
12 | type_ref::{TypeBound, TypeRef}, | 15 | type_ref::{TypeBound, TypeRef}, |
13 | visibility::Visibility, | 16 | visibility::Visibility, |
14 | AssocContainerId, Lookup, ModuleId, TraitId, | 17 | AssocContainerId, Lookup, ModuleId, TraitId, |
@@ -16,10 +19,12 @@ use hir_def::{ | |||
16 | use hir_expand::name::Name; | 19 | use hir_expand::name::Name; |
17 | 20 | ||
18 | use crate::{ | 21 | use crate::{ |
19 | db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, | 22 | const_from_placeholder_idx, db::HirDatabase, from_assoc_type_id, from_foreign_def_id, |
20 | to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, | 23 | from_placeholder_idx, lt_from_placeholder_idx, primitive, subst_prefix, to_assoc_type_id, |
21 | CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy, | 24 | traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, CallableDefId, |
22 | ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause, | 25 | CallableSig, Const, ConstValue, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, |
26 | LifetimeData, LifetimeOutlives, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, | ||
27 | QuantifiedWhereClause, Scalar, TraitRef, TraitRefExt, Ty, TyExt, TyKind, WhereClause, | ||
23 | }; | 28 | }; |
24 | 29 | ||
25 | pub struct HirFormatter<'a> { | 30 | pub struct HirFormatter<'a> { |
@@ -46,6 +51,10 @@ pub trait HirDisplay { | |||
46 | where | 51 | where |
47 | Self: Sized, | 52 | Self: Sized, |
48 | { | 53 | { |
54 | assert!( | ||
55 | !matches!(display_target, DisplayTarget::SourceCode { .. }), | ||
56 | "HirDisplayWrapper cannot fail with DisplaySourceCodeError, use HirDisplay::hir_fmt directly instead" | ||
57 | ); | ||
49 | HirDisplayWrapper { db, t: self, max_size, omit_verbose_types, display_target } | 58 | HirDisplayWrapper { db, t: self, max_size, omit_verbose_types, display_target } |
50 | } | 59 | } |
51 | 60 | ||
@@ -230,7 +239,7 @@ where | |||
230 | Err(HirDisplayError::FmtError) => Err(fmt::Error), | 239 | Err(HirDisplayError::FmtError) => Err(fmt::Error), |
231 | Err(HirDisplayError::DisplaySourceCodeError(_)) => { | 240 | Err(HirDisplayError::DisplaySourceCodeError(_)) => { |
232 | // This should never happen | 241 | // This should never happen |
233 | panic!("HirDisplay failed when calling Display::fmt!") | 242 | panic!("HirDisplay::hir_fmt failed with DisplaySourceCodeError when calling Display::fmt!") |
234 | } | 243 | } |
235 | } | 244 | } |
236 | } | 245 | } |
@@ -251,16 +260,12 @@ impl HirDisplay for ProjectionTy { | |||
251 | } | 260 | } |
252 | 261 | ||
253 | let trait_ = f.db.trait_data(self.trait_(f.db)); | 262 | let trait_ = f.db.trait_data(self.trait_(f.db)); |
254 | let first_parameter = self.substitution[0].into_displayable( | 263 | write!(f, "<")?; |
255 | f.db, | 264 | self.self_type_parameter(&Interner).hir_fmt(f)?; |
256 | f.max_size, | 265 | write!(f, " as {}", trait_.name)?; |
257 | f.omit_verbose_types, | 266 | if self.substitution.len(&Interner) > 1 { |
258 | f.display_target, | ||
259 | ); | ||
260 | write!(f, "<{} as {}", first_parameter, trait_.name)?; | ||
261 | if self.substitution.len() > 1 { | ||
262 | write!(f, "<")?; | 267 | write!(f, "<")?; |
263 | f.write_joined(&self.substitution[1..], ", ")?; | 268 | f.write_joined(&self.substitution.interned()[1..], ", ")?; |
264 | write!(f, ">")?; | 269 | write!(f, ">")?; |
265 | } | 270 | } |
266 | write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?; | 271 | write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?; |
@@ -274,7 +279,38 @@ impl HirDisplay for OpaqueTy { | |||
274 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | 279 | return write!(f, "{}", TYPE_HINT_TRUNCATION); |
275 | } | 280 | } |
276 | 281 | ||
277 | self.substitution[0].hir_fmt(f) | 282 | self.substitution.at(&Interner, 0).hir_fmt(f) |
283 | } | ||
284 | } | ||
285 | |||
286 | impl HirDisplay for GenericArg { | ||
287 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
288 | match self.interned() { | ||
289 | crate::GenericArgData::Ty(ty) => ty.hir_fmt(f), | ||
290 | } | ||
291 | } | ||
292 | } | ||
293 | |||
294 | impl HirDisplay for Const { | ||
295 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
296 | let data = self.interned(); | ||
297 | match data.value { | ||
298 | ConstValue::BoundVar(idx) => idx.hir_fmt(f), | ||
299 | ConstValue::InferenceVar(..) => write!(f, "_"), | ||
300 | ConstValue::Placeholder(idx) => { | ||
301 | let id = const_from_placeholder_idx(f.db, idx); | ||
302 | let generics = generics(f.db.upcast(), id.parent); | ||
303 | let param_data = &generics.params.consts[id.local_id]; | ||
304 | write!(f, "{}", param_data.name) | ||
305 | } | ||
306 | ConstValue::Concrete(_) => write!(f, "_"), | ||
307 | } | ||
308 | } | ||
309 | } | ||
310 | |||
311 | impl HirDisplay for BoundVar { | ||
312 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
313 | write!(f, "?{}.{}", self.debruijn.depth(), self.index) | ||
278 | } | 314 | } |
279 | } | 315 | } |
280 | 316 | ||
@@ -284,7 +320,7 @@ impl HirDisplay for Ty { | |||
284 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | 320 | return write!(f, "{}", TYPE_HINT_TRUNCATION); |
285 | } | 321 | } |
286 | 322 | ||
287 | match self.interned(&Interner) { | 323 | match self.kind(&Interner) { |
288 | TyKind::Never => write!(f, "!")?, | 324 | TyKind::Never => write!(f, "!")?, |
289 | TyKind::Str => write!(f, "str")?, | 325 | TyKind::Str => write!(f, "str")?, |
290 | TyKind::Scalar(Scalar::Bool) => write!(f, "bool")?, | 326 | TyKind::Scalar(Scalar::Bool) => write!(f, "bool")?, |
@@ -297,16 +333,15 @@ impl HirDisplay for Ty { | |||
297 | t.hir_fmt(f)?; | 333 | t.hir_fmt(f)?; |
298 | write!(f, "]")?; | 334 | write!(f, "]")?; |
299 | } | 335 | } |
300 | TyKind::Array(t) => { | 336 | TyKind::Array(t, c) => { |
301 | write!(f, "[")?; | 337 | write!(f, "[")?; |
302 | t.hir_fmt(f)?; | 338 | t.hir_fmt(f)?; |
303 | write!(f, "; _]")?; | 339 | write!(f, "; ")?; |
340 | c.hir_fmt(f)?; | ||
341 | write!(f, "]")?; | ||
304 | } | 342 | } |
305 | TyKind::Raw(m, t) | TyKind::Ref(m, t) => { | 343 | TyKind::Raw(m, t) | TyKind::Ref(m, _, t) => { |
306 | let ty_display = | 344 | if matches!(self.kind(&Interner), TyKind::Raw(..)) { |
307 | t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); | ||
308 | |||
309 | if matches!(self.interned(&Interner), TyKind::Raw(..)) { | ||
310 | write!( | 345 | write!( |
311 | f, | 346 | f, |
312 | "*{}", | 347 | "*{}", |
@@ -328,7 +363,7 @@ impl HirDisplay for Ty { | |||
328 | 363 | ||
329 | // FIXME: all this just to decide whether to use parentheses... | 364 | // FIXME: all this just to decide whether to use parentheses... |
330 | let datas; | 365 | let datas; |
331 | let predicates: Vec<_> = match t.interned(&Interner) { | 366 | let predicates: Vec<_> = match t.kind(&Interner) { |
332 | TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => { | 367 | TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => { |
333 | dyn_ty.bounds.skip_binders().interned().iter().cloned().collect() | 368 | dyn_ty.bounds.skip_binders().interned().iter().cloned().collect() |
334 | } | 369 | } |
@@ -344,8 +379,8 @@ impl HirDisplay for Ty { | |||
344 | let data = (*datas) | 379 | let data = (*datas) |
345 | .as_ref() | 380 | .as_ref() |
346 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 381 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
347 | let bounds = data.subst(parameters); | 382 | let bounds = data.substitute(&Interner, parameters); |
348 | bounds.value | 383 | bounds.into_value_and_skipped_binders().0 |
349 | } else { | 384 | } else { |
350 | Vec::new() | 385 | Vec::new() |
351 | } | 386 | } |
@@ -360,26 +395,26 @@ impl HirDisplay for Ty { | |||
360 | if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) | 395 | if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) |
361 | && predicates.len() <= 2 | 396 | && predicates.len() <= 2 |
362 | { | 397 | { |
363 | return write!(f, "{}", ty_display); | 398 | return t.hir_fmt(f); |
364 | } | 399 | } |
365 | } | 400 | } |
366 | 401 | ||
367 | if predicates.len() > 1 { | 402 | if predicates.len() > 1 { |
368 | write!(f, "(")?; | 403 | write!(f, "(")?; |
369 | write!(f, "{}", ty_display)?; | 404 | t.hir_fmt(f)?; |
370 | write!(f, ")")?; | 405 | write!(f, ")")?; |
371 | } else { | 406 | } else { |
372 | write!(f, "{}", ty_display)?; | 407 | t.hir_fmt(f)?; |
373 | } | 408 | } |
374 | } | 409 | } |
375 | TyKind::Tuple(_, substs) => { | 410 | TyKind::Tuple(_, substs) => { |
376 | if substs.len() == 1 { | 411 | if substs.len(&Interner) == 1 { |
377 | write!(f, "(")?; | 412 | write!(f, "(")?; |
378 | substs[0].hir_fmt(f)?; | 413 | substs.at(&Interner, 0).hir_fmt(f)?; |
379 | write!(f, ",)")?; | 414 | write!(f, ",)")?; |
380 | } else { | 415 | } else { |
381 | write!(f, "(")?; | 416 | write!(f, "(")?; |
382 | f.write_joined(&*substs.0, ", ")?; | 417 | f.write_joined(&*substs.interned(), ", ")?; |
383 | write!(f, ")")?; | 418 | write!(f, ")")?; |
384 | } | 419 | } |
385 | } | 420 | } |
@@ -389,7 +424,7 @@ impl HirDisplay for Ty { | |||
389 | } | 424 | } |
390 | TyKind::FnDef(def, parameters) => { | 425 | TyKind::FnDef(def, parameters) => { |
391 | let def = from_chalk(f.db, *def); | 426 | let def = from_chalk(f.db, *def); |
392 | let sig = f.db.callable_item_signature(def).subst(parameters); | 427 | let sig = f.db.callable_item_signature(def).substitute(&Interner, parameters); |
393 | match def { | 428 | match def { |
394 | CallableDefId::FunctionId(ff) => { | 429 | CallableDefId::FunctionId(ff) => { |
395 | write!(f, "fn {}", f.db.function_data(ff).name)? | 430 | write!(f, "fn {}", f.db.function_data(ff).name)? |
@@ -399,7 +434,7 @@ impl HirDisplay for Ty { | |||
399 | write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? | 434 | write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? |
400 | } | 435 | } |
401 | }; | 436 | }; |
402 | if parameters.len() > 0 { | 437 | if parameters.len(&Interner) > 0 { |
403 | let generics = generics(f.db.upcast(), def.into()); | 438 | let generics = generics(f.db.upcast(), def.into()); |
404 | let (parent_params, self_param, type_params, _impl_trait_params) = | 439 | let (parent_params, self_param, type_params, _impl_trait_params) = |
405 | generics.provenance_split(); | 440 | generics.provenance_split(); |
@@ -407,7 +442,7 @@ impl HirDisplay for Ty { | |||
407 | // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? | 442 | // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? |
408 | if total_len > 0 { | 443 | if total_len > 0 { |
409 | write!(f, "<")?; | 444 | write!(f, "<")?; |
410 | f.write_joined(¶meters.0[..total_len], ", ")?; | 445 | f.write_joined(¶meters.interned()[..total_len], ", ")?; |
411 | write!(f, ">")?; | 446 | write!(f, ">")?; |
412 | } | 447 | } |
413 | } | 448 | } |
@@ -415,15 +450,9 @@ impl HirDisplay for Ty { | |||
415 | f.write_joined(sig.params(), ", ")?; | 450 | f.write_joined(sig.params(), ", ")?; |
416 | write!(f, ")")?; | 451 | write!(f, ")")?; |
417 | let ret = sig.ret(); | 452 | let ret = sig.ret(); |
418 | if *ret != Ty::unit() { | 453 | if !ret.is_unit() { |
419 | let ret_display = ret.into_displayable( | 454 | write!(f, " -> ")?; |
420 | f.db, | 455 | ret.hir_fmt(f)?; |
421 | f.max_size, | ||
422 | f.omit_verbose_types, | ||
423 | f.display_target, | ||
424 | ); | ||
425 | |||
426 | write!(f, " -> {}", ret_display)?; | ||
427 | } | 456 | } |
428 | } | 457 | } |
429 | TyKind::Adt(AdtId(def_id), parameters) => { | 458 | TyKind::Adt(AdtId(def_id), parameters) => { |
@@ -451,7 +480,7 @@ impl HirDisplay for Ty { | |||
451 | } | 480 | } |
452 | } | 481 | } |
453 | 482 | ||
454 | if parameters.len() > 0 { | 483 | if parameters.len(&Interner) > 0 { |
455 | let parameters_to_write = if f.display_target.is_source_code() | 484 | let parameters_to_write = if f.display_target.is_source_code() |
456 | || f.omit_verbose_types() | 485 | || f.omit_verbose_types() |
457 | { | 486 | { |
@@ -460,30 +489,35 @@ impl HirDisplay for Ty { | |||
460 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) | 489 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) |
461 | .filter(|defaults| !defaults.is_empty()) | 490 | .filter(|defaults| !defaults.is_empty()) |
462 | { | 491 | { |
463 | None => parameters.0.as_ref(), | 492 | None => parameters.interned().as_ref(), |
464 | Some(default_parameters) => { | 493 | Some(default_parameters) => { |
465 | let mut default_from = 0; | 494 | let mut default_from = 0; |
466 | for (i, parameter) in parameters.iter().enumerate() { | 495 | for (i, parameter) in parameters.iter(&Interner).enumerate() { |
467 | match (parameter.interned(&Interner), default_parameters.get(i)) | 496 | match ( |
468 | { | 497 | parameter.assert_ty_ref(&Interner).kind(&Interner), |
469 | (&TyKind::Unknown, _) | (_, None) => { | 498 | default_parameters.get(i), |
499 | ) { | ||
500 | (&TyKind::Error, _) | (_, None) => { | ||
470 | default_from = i + 1; | 501 | default_from = i + 1; |
471 | } | 502 | } |
472 | (_, Some(default_parameter)) => { | 503 | (_, Some(default_parameter)) => { |
473 | let actual_default = default_parameter | 504 | let actual_default = |
474 | .clone() | 505 | default_parameter.clone().substitute( |
475 | .subst(¶meters.prefix(i)); | 506 | &Interner, |
476 | if parameter != &actual_default { | 507 | &subst_prefix(parameters, i), |
508 | ); | ||
509 | if parameter.assert_ty_ref(&Interner) != &actual_default | ||
510 | { | ||
477 | default_from = i + 1; | 511 | default_from = i + 1; |
478 | } | 512 | } |
479 | } | 513 | } |
480 | } | 514 | } |
481 | } | 515 | } |
482 | ¶meters.0[0..default_from] | 516 | ¶meters.interned()[0..default_from] |
483 | } | 517 | } |
484 | } | 518 | } |
485 | } else { | 519 | } else { |
486 | parameters.0.as_ref() | 520 | parameters.interned().as_ref() |
487 | }; | 521 | }; |
488 | if !parameters_to_write.is_empty() { | 522 | if !parameters_to_write.is_empty() { |
489 | write!(f, "<")?; | 523 | write!(f, "<")?; |
@@ -504,9 +538,9 @@ impl HirDisplay for Ty { | |||
504 | // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) | 538 | // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) |
505 | if f.display_target.is_test() { | 539 | if f.display_target.is_test() { |
506 | write!(f, "{}::{}", trait_.name, type_alias_data.name)?; | 540 | write!(f, "{}::{}", trait_.name, type_alias_data.name)?; |
507 | if parameters.len() > 0 { | 541 | if parameters.len(&Interner) > 0 { |
508 | write!(f, "<")?; | 542 | write!(f, "<")?; |
509 | f.write_joined(&*parameters.0, ", ")?; | 543 | f.write_joined(&*parameters.interned(), ", ")?; |
510 | write!(f, ">")?; | 544 | write!(f, ">")?; |
511 | } | 545 | } |
512 | } else { | 546 | } else { |
@@ -518,7 +552,7 @@ impl HirDisplay for Ty { | |||
518 | projection_ty.hir_fmt(f)?; | 552 | projection_ty.hir_fmt(f)?; |
519 | } | 553 | } |
520 | } | 554 | } |
521 | TyKind::ForeignType(type_alias) => { | 555 | TyKind::Foreign(type_alias) => { |
522 | let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias)); | 556 | let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias)); |
523 | write!(f, "{}", type_alias.name)?; | 557 | write!(f, "{}", type_alias.name)?; |
524 | } | 558 | } |
@@ -531,13 +565,13 @@ impl HirDisplay for Ty { | |||
531 | let data = (*datas) | 565 | let data = (*datas) |
532 | .as_ref() | 566 | .as_ref() |
533 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 567 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
534 | let bounds = data.subst(¶meters); | 568 | let bounds = data.substitute(&Interner, ¶meters); |
535 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 569 | write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?; |
536 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution | 570 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution |
537 | } | 571 | } |
538 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { | 572 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { |
539 | write!(f, "impl Future<Output = ")?; | 573 | write!(f, "impl Future<Output = ")?; |
540 | parameters[0].hir_fmt(f)?; | 574 | parameters.at(&Interner, 0).hir_fmt(f)?; |
541 | write!(f, ">")?; | 575 | write!(f, ">")?; |
542 | } | 576 | } |
543 | } | 577 | } |
@@ -548,7 +582,7 @@ impl HirDisplay for Ty { | |||
548 | DisplaySourceCodeError::Closure, | 582 | DisplaySourceCodeError::Closure, |
549 | )); | 583 | )); |
550 | } | 584 | } |
551 | let sig = substs[0].callable_sig(f.db); | 585 | let sig = substs.at(&Interner, 0).assert_ty_ref(&Interner).callable_sig(f.db); |
552 | if let Some(sig) = sig { | 586 | if let Some(sig) = sig { |
553 | if sig.params().is_empty() { | 587 | if sig.params().is_empty() { |
554 | write!(f, "||")?; | 588 | write!(f, "||")?; |
@@ -560,13 +594,8 @@ impl HirDisplay for Ty { | |||
560 | write!(f, "|")?; | 594 | write!(f, "|")?; |
561 | }; | 595 | }; |
562 | 596 | ||
563 | let ret_display = sig.ret().into_displayable( | 597 | write!(f, " -> ")?; |
564 | f.db, | 598 | sig.ret().hir_fmt(f)?; |
565 | f.max_size, | ||
566 | f.omit_verbose_types, | ||
567 | f.display_target, | ||
568 | ); | ||
569 | write!(f, " -> {}", ret_display)?; | ||
570 | } else { | 599 | } else { |
571 | write!(f, "{{closure}}")?; | 600 | write!(f, "{{closure}}")?; |
572 | } | 601 | } |
@@ -580,26 +609,27 @@ impl HirDisplay for Ty { | |||
580 | write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? | 609 | write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? |
581 | } | 610 | } |
582 | TypeParamProvenance::ArgumentImplTrait => { | 611 | TypeParamProvenance::ArgumentImplTrait => { |
583 | let substs = Substitution::type_params_for_generics(f.db, &generics); | 612 | let substs = generics.type_params_subst(f.db); |
584 | let bounds = f | 613 | let bounds = |
585 | .db | 614 | f.db.generic_predicates(id.parent) |
586 | .generic_predicates(id.parent) | 615 | .into_iter() |
587 | .into_iter() | 616 | .map(|pred| pred.clone().substitute(&Interner, &substs)) |
588 | .map(|pred| pred.clone().subst(&substs)) | 617 | .filter(|wc| match &wc.skip_binders() { |
589 | .filter(|wc| match &wc.skip_binders() { | 618 | WhereClause::Implemented(tr) => { |
590 | WhereClause::Implemented(tr) => tr.self_type_parameter() == self, | 619 | &tr.self_type_parameter(&Interner) == self |
591 | WhereClause::AliasEq(AliasEq { | 620 | } |
592 | alias: AliasTy::Projection(proj), | 621 | WhereClause::AliasEq(AliasEq { |
593 | ty: _, | 622 | alias: AliasTy::Projection(proj), |
594 | }) => proj.self_type_parameter() == self, | 623 | ty: _, |
595 | _ => false, | 624 | }) => &proj.self_type_parameter(&Interner) == self, |
596 | }) | 625 | _ => false, |
597 | .collect::<Vec<_>>(); | 626 | }) |
627 | .collect::<Vec<_>>(); | ||
598 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?; | 628 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?; |
599 | } | 629 | } |
600 | } | 630 | } |
601 | } | 631 | } |
602 | TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, | 632 | TyKind::BoundVar(idx) => idx.hir_fmt(f)?, |
603 | TyKind::Dyn(dyn_ty) => { | 633 | TyKind::Dyn(dyn_ty) => { |
604 | write_bounds_like_dyn_trait_with_prefix( | 634 | write_bounds_like_dyn_trait_with_prefix( |
605 | "dyn", | 635 | "dyn", |
@@ -617,15 +647,15 @@ impl HirDisplay for Ty { | |||
617 | let data = (*datas) | 647 | let data = (*datas) |
618 | .as_ref() | 648 | .as_ref() |
619 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 649 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
620 | let bounds = data.subst(&opaque_ty.substitution); | 650 | let bounds = data.substitute(&Interner, &opaque_ty.substitution); |
621 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 651 | write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?; |
622 | } | 652 | } |
623 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { | 653 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { |
624 | write!(f, "{{async block}}")?; | 654 | write!(f, "{{async block}}")?; |
625 | } | 655 | } |
626 | }; | 656 | }; |
627 | } | 657 | } |
628 | TyKind::Unknown => { | 658 | TyKind::Error => { |
629 | if f.display_target.is_source_code() { | 659 | if f.display_target.is_source_code() { |
630 | return Err(HirDisplayError::DisplaySourceCodeError( | 660 | return Err(HirDisplayError::DisplaySourceCodeError( |
631 | DisplaySourceCodeError::UnknownType, | 661 | DisplaySourceCodeError::UnknownType, |
@@ -652,10 +682,9 @@ impl HirDisplay for CallableSig { | |||
652 | } | 682 | } |
653 | write!(f, ")")?; | 683 | write!(f, ")")?; |
654 | let ret = self.ret(); | 684 | let ret = self.ret(); |
655 | if *ret != Ty::unit() { | 685 | if !ret.is_unit() { |
656 | let ret_display = | 686 | write!(f, " -> ")?; |
657 | ret.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); | 687 | ret.hir_fmt(f)?; |
658 | write!(f, " -> {}", ret_display)?; | ||
659 | } | 688 | } |
660 | Ok(()) | 689 | Ok(()) |
661 | } | 690 | } |
@@ -716,11 +745,13 @@ fn write_bounds_like_dyn_trait( | |||
716 | // existential) here, which is the only thing that's | 745 | // existential) here, which is the only thing that's |
717 | // possible in actual Rust, and hence don't print it | 746 | // possible in actual Rust, and hence don't print it |
718 | write!(f, "{}", f.db.trait_data(trait_).name)?; | 747 | write!(f, "{}", f.db.trait_data(trait_).name)?; |
719 | if let [_, params @ ..] = &*trait_ref.substitution.0 { | 748 | if let [_, params @ ..] = &*trait_ref.substitution.interned().as_slice() { |
720 | if is_fn_trait { | 749 | if is_fn_trait { |
721 | if let Some(args) = params.first().and_then(|it| it.as_tuple()) { | 750 | if let Some(args) = |
751 | params.first().and_then(|it| it.assert_ty_ref(&Interner).as_tuple()) | ||
752 | { | ||
722 | write!(f, "(")?; | 753 | write!(f, "(")?; |
723 | f.write_joined(&*args.0, ", ")?; | 754 | f.write_joined(&*args.interned(), ", ")?; |
724 | write!(f, ")")?; | 755 | write!(f, ")")?; |
725 | } | 756 | } |
726 | } else if !params.is_empty() { | 757 | } else if !params.is_empty() { |
@@ -761,31 +792,29 @@ fn write_bounds_like_dyn_trait( | |||
761 | Ok(()) | 792 | Ok(()) |
762 | } | 793 | } |
763 | 794 | ||
764 | impl TraitRef { | 795 | fn fmt_trait_ref(tr: &TraitRef, f: &mut HirFormatter, use_as: bool) -> Result<(), HirDisplayError> { |
765 | fn hir_fmt_ext(&self, f: &mut HirFormatter, use_as: bool) -> Result<(), HirDisplayError> { | 796 | if f.should_truncate() { |
766 | if f.should_truncate() { | 797 | return write!(f, "{}", TYPE_HINT_TRUNCATION); |
767 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | 798 | } |
768 | } | ||
769 | 799 | ||
770 | self.substitution[0].hir_fmt(f)?; | 800 | tr.self_type_parameter(&Interner).hir_fmt(f)?; |
771 | if use_as { | 801 | if use_as { |
772 | write!(f, " as ")?; | 802 | write!(f, " as ")?; |
773 | } else { | 803 | } else { |
774 | write!(f, ": ")?; | 804 | write!(f, ": ")?; |
775 | } | ||
776 | write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?; | ||
777 | if self.substitution.len() > 1 { | ||
778 | write!(f, "<")?; | ||
779 | f.write_joined(&self.substitution[1..], ", ")?; | ||
780 | write!(f, ">")?; | ||
781 | } | ||
782 | Ok(()) | ||
783 | } | 805 | } |
806 | write!(f, "{}", f.db.trait_data(tr.hir_trait_id()).name)?; | ||
807 | if tr.substitution.len(&Interner) > 1 { | ||
808 | write!(f, "<")?; | ||
809 | f.write_joined(&tr.substitution.interned()[1..], ", ")?; | ||
810 | write!(f, ">")?; | ||
811 | } | ||
812 | Ok(()) | ||
784 | } | 813 | } |
785 | 814 | ||
786 | impl HirDisplay for TraitRef { | 815 | impl HirDisplay for TraitRef { |
787 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 816 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
788 | self.hir_fmt_ext(f, false) | 817 | fmt_trait_ref(self, f, false) |
789 | } | 818 | } |
790 | } | 819 | } |
791 | 820 | ||
@@ -799,7 +828,7 @@ impl HirDisplay for WhereClause { | |||
799 | WhereClause::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, | 828 | WhereClause::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, |
800 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { | 829 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { |
801 | write!(f, "<")?; | 830 | write!(f, "<")?; |
802 | projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?; | 831 | fmt_trait_ref(&projection_ty.trait_ref(f.db), f, true)?; |
803 | write!( | 832 | write!( |
804 | f, | 833 | f, |
805 | ">::{} = ", | 834 | ">::{} = ", |
@@ -813,15 +842,35 @@ impl HirDisplay for WhereClause { | |||
813 | } | 842 | } |
814 | } | 843 | } |
815 | 844 | ||
845 | impl HirDisplay for LifetimeOutlives { | ||
846 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
847 | self.a.hir_fmt(f)?; | ||
848 | write!(f, ": ")?; | ||
849 | self.b.hir_fmt(f) | ||
850 | } | ||
851 | } | ||
852 | |||
816 | impl HirDisplay for Lifetime { | 853 | impl HirDisplay for Lifetime { |
817 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 854 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
855 | self.interned().hir_fmt(f) | ||
856 | } | ||
857 | } | ||
858 | |||
859 | impl HirDisplay for LifetimeData { | ||
860 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
818 | match self { | 861 | match self { |
819 | Lifetime::Parameter(id) => { | 862 | LifetimeData::BoundVar(idx) => idx.hir_fmt(f), |
863 | LifetimeData::InferenceVar(_) => write!(f, "_"), | ||
864 | LifetimeData::Placeholder(idx) => { | ||
865 | let id = lt_from_placeholder_idx(f.db, *idx); | ||
820 | let generics = generics(f.db.upcast(), id.parent); | 866 | let generics = generics(f.db.upcast(), id.parent); |
821 | let param_data = &generics.params.lifetimes[id.local_id]; | 867 | let param_data = &generics.params.lifetimes[id.local_id]; |
822 | write!(f, "{}", ¶m_data.name) | 868 | write!(f, "{}", param_data.name) |
823 | } | 869 | } |
824 | Lifetime::Static => write!(f, "'static"), | 870 | LifetimeData::Static => write!(f, "'static"), |
871 | LifetimeData::Empty(_) => Ok(()), | ||
872 | LifetimeData::Erased => Ok(()), | ||
873 | LifetimeData::Phantom(_, _) => Ok(()), | ||
825 | } | 874 | } |
826 | } | 875 | } |
827 | } | 876 | } |
@@ -1016,11 +1065,11 @@ impl HirDisplay for Path { | |||
1016 | } | 1065 | } |
1017 | } | 1066 | } |
1018 | 1067 | ||
1019 | impl HirDisplay for GenericArg { | 1068 | impl HirDisplay for hir_def::path::GenericArg { |
1020 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 1069 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
1021 | match self { | 1070 | match self { |
1022 | GenericArg::Type(ty) => ty.hir_fmt(f), | 1071 | hir_def::path::GenericArg::Type(ty) => ty.hir_fmt(f), |
1023 | GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name), | 1072 | hir_def::path::GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name), |
1024 | } | 1073 | } |
1025 | } | 1074 | } |
1026 | } | 1075 | } |