diff options
Diffstat (limited to 'crates/hir_ty/src/display.rs')
-rw-r--r-- | crates/hir_ty/src/display.rs | 321 |
1 files changed, 193 insertions, 128 deletions
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 51480304b..e7c9dabc2 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -1,14 +1,19 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! The `HirDisplay` trait, which serves two purposes: Turning various bits from |
2 | //! HIR back into source code, and just displaying them for debugging/testing | ||
3 | //! purposes. | ||
2 | 4 | ||
3 | use std::{array, fmt}; | 5 | use std::{ |
6 | array, | ||
7 | fmt::{self, Debug}, | ||
8 | }; | ||
4 | 9 | ||
5 | use chalk_ir::Mutability; | 10 | use chalk_ir::BoundVar; |
6 | use hir_def::{ | 11 | use hir_def::{ |
7 | db::DefDatabase, | 12 | db::DefDatabase, |
8 | find_path, | 13 | find_path, |
9 | generics::TypeParamProvenance, | 14 | generics::TypeParamProvenance, |
10 | item_scope::ItemInNs, | 15 | item_scope::ItemInNs, |
11 | path::{GenericArg, Path, PathKind}, | 16 | path::{Path, PathKind}, |
12 | type_ref::{TypeBound, TypeRef}, | 17 | type_ref::{TypeBound, TypeRef}, |
13 | visibility::Visibility, | 18 | visibility::Visibility, |
14 | AssocContainerId, Lookup, ModuleId, TraitId, | 19 | AssocContainerId, Lookup, ModuleId, TraitId, |
@@ -16,10 +21,12 @@ use hir_def::{ | |||
16 | use hir_expand::name::Name; | 21 | use hir_expand::name::Name; |
17 | 22 | ||
18 | use crate::{ | 23 | use crate::{ |
19 | db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, | 24 | 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, | 25 | from_placeholder_idx, lt_from_placeholder_idx, mapping::from_chalk, primitive, subst_prefix, |
21 | CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy, | 26 | to_assoc_type_id, utils::generics, AdtId, AliasEq, AliasTy, CallableDefId, CallableSig, Const, |
22 | ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause, | 27 | ConstValue, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData, |
28 | LifetimeOutlives, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, | ||
29 | Scalar, TraitRef, TraitRefExt, Ty, TyExt, TyKind, WhereClause, | ||
23 | }; | 30 | }; |
24 | 31 | ||
25 | pub struct HirFormatter<'a> { | 32 | pub struct HirFormatter<'a> { |
@@ -46,6 +53,10 @@ pub trait HirDisplay { | |||
46 | where | 53 | where |
47 | Self: Sized, | 54 | Self: Sized, |
48 | { | 55 | { |
56 | assert!( | ||
57 | !matches!(display_target, DisplayTarget::SourceCode { .. }), | ||
58 | "HirDisplayWrapper cannot fail with DisplaySourceCodeError, use HirDisplay::hir_fmt directly instead" | ||
59 | ); | ||
49 | HirDisplayWrapper { db, t: self, max_size, omit_verbose_types, display_target } | 60 | HirDisplayWrapper { db, t: self, max_size, omit_verbose_types, display_target } |
50 | } | 61 | } |
51 | 62 | ||
@@ -230,7 +241,7 @@ where | |||
230 | Err(HirDisplayError::FmtError) => Err(fmt::Error), | 241 | Err(HirDisplayError::FmtError) => Err(fmt::Error), |
231 | Err(HirDisplayError::DisplaySourceCodeError(_)) => { | 242 | Err(HirDisplayError::DisplaySourceCodeError(_)) => { |
232 | // This should never happen | 243 | // This should never happen |
233 | panic!("HirDisplay failed when calling Display::fmt!") | 244 | panic!("HirDisplay::hir_fmt failed with DisplaySourceCodeError when calling Display::fmt!") |
234 | } | 245 | } |
235 | } | 246 | } |
236 | } | 247 | } |
@@ -251,16 +262,12 @@ impl HirDisplay for ProjectionTy { | |||
251 | } | 262 | } |
252 | 263 | ||
253 | let trait_ = f.db.trait_data(self.trait_(f.db)); | 264 | let trait_ = f.db.trait_data(self.trait_(f.db)); |
254 | let first_parameter = self.substitution[0].into_displayable( | 265 | write!(f, "<")?; |
255 | f.db, | 266 | self.self_type_parameter(&Interner).hir_fmt(f)?; |
256 | f.max_size, | 267 | write!(f, " as {}", trait_.name)?; |
257 | f.omit_verbose_types, | 268 | 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, "<")?; | 269 | write!(f, "<")?; |
263 | f.write_joined(&self.substitution[1..], ", ")?; | 270 | f.write_joined(&self.substitution.as_slice(&Interner)[1..], ", ")?; |
264 | write!(f, ">")?; | 271 | write!(f, ">")?; |
265 | } | 272 | } |
266 | write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?; | 273 | write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?; |
@@ -274,7 +281,40 @@ impl HirDisplay for OpaqueTy { | |||
274 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | 281 | return write!(f, "{}", TYPE_HINT_TRUNCATION); |
275 | } | 282 | } |
276 | 283 | ||
277 | self.substitution[0].hir_fmt(f) | 284 | self.substitution.at(&Interner, 0).hir_fmt(f) |
285 | } | ||
286 | } | ||
287 | |||
288 | impl HirDisplay for GenericArg { | ||
289 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
290 | match self.interned() { | ||
291 | crate::GenericArgData::Ty(ty) => ty.hir_fmt(f), | ||
292 | crate::GenericArgData::Lifetime(lt) => lt.hir_fmt(f), | ||
293 | crate::GenericArgData::Const(c) => c.hir_fmt(f), | ||
294 | } | ||
295 | } | ||
296 | } | ||
297 | |||
298 | impl HirDisplay for Const { | ||
299 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
300 | let data = self.interned(); | ||
301 | match data.value { | ||
302 | ConstValue::BoundVar(idx) => idx.hir_fmt(f), | ||
303 | ConstValue::InferenceVar(..) => write!(f, "_"), | ||
304 | ConstValue::Placeholder(idx) => { | ||
305 | let id = const_from_placeholder_idx(f.db, idx); | ||
306 | let generics = generics(f.db.upcast(), id.parent); | ||
307 | let param_data = &generics.params.consts[id.local_id]; | ||
308 | write!(f, "{}", param_data.name) | ||
309 | } | ||
310 | ConstValue::Concrete(_) => write!(f, "_"), | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | |||
315 | impl HirDisplay for BoundVar { | ||
316 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
317 | write!(f, "?{}.{}", self.debruijn.depth(), self.index) | ||
278 | } | 318 | } |
279 | } | 319 | } |
280 | 320 | ||
@@ -284,7 +324,7 @@ impl HirDisplay for Ty { | |||
284 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | 324 | return write!(f, "{}", TYPE_HINT_TRUNCATION); |
285 | } | 325 | } |
286 | 326 | ||
287 | match self.interned(&Interner) { | 327 | match self.kind(&Interner) { |
288 | TyKind::Never => write!(f, "!")?, | 328 | TyKind::Never => write!(f, "!")?, |
289 | TyKind::Str => write!(f, "str")?, | 329 | TyKind::Str => write!(f, "str")?, |
290 | TyKind::Scalar(Scalar::Bool) => write!(f, "bool")?, | 330 | TyKind::Scalar(Scalar::Bool) => write!(f, "bool")?, |
@@ -297,16 +337,15 @@ impl HirDisplay for Ty { | |||
297 | t.hir_fmt(f)?; | 337 | t.hir_fmt(f)?; |
298 | write!(f, "]")?; | 338 | write!(f, "]")?; |
299 | } | 339 | } |
300 | TyKind::Array(t) => { | 340 | TyKind::Array(t, c) => { |
301 | write!(f, "[")?; | 341 | write!(f, "[")?; |
302 | t.hir_fmt(f)?; | 342 | t.hir_fmt(f)?; |
303 | write!(f, "; _]")?; | 343 | write!(f, "; ")?; |
344 | c.hir_fmt(f)?; | ||
345 | write!(f, "]")?; | ||
304 | } | 346 | } |
305 | TyKind::Raw(m, t) | TyKind::Ref(m, t) => { | 347 | TyKind::Raw(m, t) | TyKind::Ref(m, _, t) => { |
306 | let ty_display = | 348 | 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!( | 349 | write!( |
311 | f, | 350 | f, |
312 | "*{}", | 351 | "*{}", |
@@ -328,7 +367,7 @@ impl HirDisplay for Ty { | |||
328 | 367 | ||
329 | // FIXME: all this just to decide whether to use parentheses... | 368 | // FIXME: all this just to decide whether to use parentheses... |
330 | let datas; | 369 | let datas; |
331 | let predicates: Vec<_> = match t.interned(&Interner) { | 370 | let predicates: Vec<_> = match t.kind(&Interner) { |
332 | TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => { | 371 | TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => { |
333 | dyn_ty.bounds.skip_binders().interned().iter().cloned().collect() | 372 | dyn_ty.bounds.skip_binders().interned().iter().cloned().collect() |
334 | } | 373 | } |
@@ -344,8 +383,8 @@ impl HirDisplay for Ty { | |||
344 | let data = (*datas) | 383 | let data = (*datas) |
345 | .as_ref() | 384 | .as_ref() |
346 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 385 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
347 | let bounds = data.subst(parameters); | 386 | let bounds = data.substitute(&Interner, parameters); |
348 | bounds.value | 387 | bounds.into_value_and_skipped_binders().0 |
349 | } else { | 388 | } else { |
350 | Vec::new() | 389 | Vec::new() |
351 | } | 390 | } |
@@ -360,26 +399,26 @@ impl HirDisplay for Ty { | |||
360 | if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) | 399 | if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) |
361 | && predicates.len() <= 2 | 400 | && predicates.len() <= 2 |
362 | { | 401 | { |
363 | return write!(f, "{}", ty_display); | 402 | return t.hir_fmt(f); |
364 | } | 403 | } |
365 | } | 404 | } |
366 | 405 | ||
367 | if predicates.len() > 1 { | 406 | if predicates.len() > 1 { |
368 | write!(f, "(")?; | 407 | write!(f, "(")?; |
369 | write!(f, "{}", ty_display)?; | 408 | t.hir_fmt(f)?; |
370 | write!(f, ")")?; | 409 | write!(f, ")")?; |
371 | } else { | 410 | } else { |
372 | write!(f, "{}", ty_display)?; | 411 | t.hir_fmt(f)?; |
373 | } | 412 | } |
374 | } | 413 | } |
375 | TyKind::Tuple(_, substs) => { | 414 | TyKind::Tuple(_, substs) => { |
376 | if substs.len() == 1 { | 415 | if substs.len(&Interner) == 1 { |
377 | write!(f, "(")?; | 416 | write!(f, "(")?; |
378 | substs[0].hir_fmt(f)?; | 417 | substs.at(&Interner, 0).hir_fmt(f)?; |
379 | write!(f, ",)")?; | 418 | write!(f, ",)")?; |
380 | } else { | 419 | } else { |
381 | write!(f, "(")?; | 420 | write!(f, "(")?; |
382 | f.write_joined(&*substs.0, ", ")?; | 421 | f.write_joined(&*substs.as_slice(&Interner), ", ")?; |
383 | write!(f, ")")?; | 422 | write!(f, ")")?; |
384 | } | 423 | } |
385 | } | 424 | } |
@@ -389,7 +428,7 @@ impl HirDisplay for Ty { | |||
389 | } | 428 | } |
390 | TyKind::FnDef(def, parameters) => { | 429 | TyKind::FnDef(def, parameters) => { |
391 | let def = from_chalk(f.db, *def); | 430 | let def = from_chalk(f.db, *def); |
392 | let sig = f.db.callable_item_signature(def).subst(parameters); | 431 | let sig = f.db.callable_item_signature(def).substitute(&Interner, parameters); |
393 | match def { | 432 | match def { |
394 | CallableDefId::FunctionId(ff) => { | 433 | CallableDefId::FunctionId(ff) => { |
395 | write!(f, "fn {}", f.db.function_data(ff).name)? | 434 | write!(f, "fn {}", f.db.function_data(ff).name)? |
@@ -399,7 +438,7 @@ impl HirDisplay for Ty { | |||
399 | write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? | 438 | write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? |
400 | } | 439 | } |
401 | }; | 440 | }; |
402 | if parameters.len() > 0 { | 441 | if parameters.len(&Interner) > 0 { |
403 | let generics = generics(f.db.upcast(), def.into()); | 442 | let generics = generics(f.db.upcast(), def.into()); |
404 | let (parent_params, self_param, type_params, _impl_trait_params) = | 443 | let (parent_params, self_param, type_params, _impl_trait_params) = |
405 | generics.provenance_split(); | 444 | generics.provenance_split(); |
@@ -407,7 +446,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? | 446 | // 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 { | 447 | if total_len > 0 { |
409 | write!(f, "<")?; | 448 | write!(f, "<")?; |
410 | f.write_joined(¶meters.0[..total_len], ", ")?; | 449 | f.write_joined(¶meters.as_slice(&Interner)[..total_len], ", ")?; |
411 | write!(f, ">")?; | 450 | write!(f, ">")?; |
412 | } | 451 | } |
413 | } | 452 | } |
@@ -415,15 +454,9 @@ impl HirDisplay for Ty { | |||
415 | f.write_joined(sig.params(), ", ")?; | 454 | f.write_joined(sig.params(), ", ")?; |
416 | write!(f, ")")?; | 455 | write!(f, ")")?; |
417 | let ret = sig.ret(); | 456 | let ret = sig.ret(); |
418 | if *ret != Ty::unit() { | 457 | if !ret.is_unit() { |
419 | let ret_display = ret.into_displayable( | 458 | write!(f, " -> ")?; |
420 | f.db, | 459 | 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 | } | 460 | } |
428 | } | 461 | } |
429 | TyKind::Adt(AdtId(def_id), parameters) => { | 462 | TyKind::Adt(AdtId(def_id), parameters) => { |
@@ -451,7 +484,7 @@ impl HirDisplay for Ty { | |||
451 | } | 484 | } |
452 | } | 485 | } |
453 | 486 | ||
454 | if parameters.len() > 0 { | 487 | if parameters.len(&Interner) > 0 { |
455 | let parameters_to_write = if f.display_target.is_source_code() | 488 | let parameters_to_write = if f.display_target.is_source_code() |
456 | || f.omit_verbose_types() | 489 | || f.omit_verbose_types() |
457 | { | 490 | { |
@@ -460,30 +493,35 @@ impl HirDisplay for Ty { | |||
460 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) | 493 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) |
461 | .filter(|defaults| !defaults.is_empty()) | 494 | .filter(|defaults| !defaults.is_empty()) |
462 | { | 495 | { |
463 | None => parameters.0.as_ref(), | 496 | None => parameters.as_slice(&Interner), |
464 | Some(default_parameters) => { | 497 | Some(default_parameters) => { |
465 | let mut default_from = 0; | 498 | let mut default_from = 0; |
466 | for (i, parameter) in parameters.iter().enumerate() { | 499 | for (i, parameter) in parameters.iter(&Interner).enumerate() { |
467 | match (parameter.interned(&Interner), default_parameters.get(i)) | 500 | match ( |
468 | { | 501 | parameter.assert_ty_ref(&Interner).kind(&Interner), |
469 | (&TyKind::Unknown, _) | (_, None) => { | 502 | default_parameters.get(i), |
503 | ) { | ||
504 | (&TyKind::Error, _) | (_, None) => { | ||
470 | default_from = i + 1; | 505 | default_from = i + 1; |
471 | } | 506 | } |
472 | (_, Some(default_parameter)) => { | 507 | (_, Some(default_parameter)) => { |
473 | let actual_default = default_parameter | 508 | let actual_default = |
474 | .clone() | 509 | default_parameter.clone().substitute( |
475 | .subst(¶meters.prefix(i)); | 510 | &Interner, |
476 | if parameter != &actual_default { | 511 | &subst_prefix(parameters, i), |
512 | ); | ||
513 | if parameter.assert_ty_ref(&Interner) != &actual_default | ||
514 | { | ||
477 | default_from = i + 1; | 515 | default_from = i + 1; |
478 | } | 516 | } |
479 | } | 517 | } |
480 | } | 518 | } |
481 | } | 519 | } |
482 | ¶meters.0[0..default_from] | 520 | ¶meters.as_slice(&Interner)[0..default_from] |
483 | } | 521 | } |
484 | } | 522 | } |
485 | } else { | 523 | } else { |
486 | parameters.0.as_ref() | 524 | parameters.as_slice(&Interner) |
487 | }; | 525 | }; |
488 | if !parameters_to_write.is_empty() { | 526 | if !parameters_to_write.is_empty() { |
489 | write!(f, "<")?; | 527 | write!(f, "<")?; |
@@ -504,9 +542,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) | 542 | // 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() { | 543 | if f.display_target.is_test() { |
506 | write!(f, "{}::{}", trait_.name, type_alias_data.name)?; | 544 | write!(f, "{}::{}", trait_.name, type_alias_data.name)?; |
507 | if parameters.len() > 0 { | 545 | if parameters.len(&Interner) > 0 { |
508 | write!(f, "<")?; | 546 | write!(f, "<")?; |
509 | f.write_joined(&*parameters.0, ", ")?; | 547 | f.write_joined(&*parameters.as_slice(&Interner), ", ")?; |
510 | write!(f, ">")?; | 548 | write!(f, ">")?; |
511 | } | 549 | } |
512 | } else { | 550 | } else { |
@@ -518,7 +556,7 @@ impl HirDisplay for Ty { | |||
518 | projection_ty.hir_fmt(f)?; | 556 | projection_ty.hir_fmt(f)?; |
519 | } | 557 | } |
520 | } | 558 | } |
521 | TyKind::ForeignType(type_alias) => { | 559 | TyKind::Foreign(type_alias) => { |
522 | let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias)); | 560 | let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias)); |
523 | write!(f, "{}", type_alias.name)?; | 561 | write!(f, "{}", type_alias.name)?; |
524 | } | 562 | } |
@@ -531,13 +569,13 @@ impl HirDisplay for Ty { | |||
531 | let data = (*datas) | 569 | let data = (*datas) |
532 | .as_ref() | 570 | .as_ref() |
533 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 571 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
534 | let bounds = data.subst(¶meters); | 572 | let bounds = data.substitute(&Interner, ¶meters); |
535 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 573 | 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 | 574 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution |
537 | } | 575 | } |
538 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { | 576 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { |
539 | write!(f, "impl Future<Output = ")?; | 577 | write!(f, "impl Future<Output = ")?; |
540 | parameters[0].hir_fmt(f)?; | 578 | parameters.at(&Interner, 0).hir_fmt(f)?; |
541 | write!(f, ">")?; | 579 | write!(f, ">")?; |
542 | } | 580 | } |
543 | } | 581 | } |
@@ -548,7 +586,7 @@ impl HirDisplay for Ty { | |||
548 | DisplaySourceCodeError::Closure, | 586 | DisplaySourceCodeError::Closure, |
549 | )); | 587 | )); |
550 | } | 588 | } |
551 | let sig = substs[0].callable_sig(f.db); | 589 | let sig = substs.at(&Interner, 0).assert_ty_ref(&Interner).callable_sig(f.db); |
552 | if let Some(sig) = sig { | 590 | if let Some(sig) = sig { |
553 | if sig.params().is_empty() { | 591 | if sig.params().is_empty() { |
554 | write!(f, "||")?; | 592 | write!(f, "||")?; |
@@ -560,13 +598,8 @@ impl HirDisplay for Ty { | |||
560 | write!(f, "|")?; | 598 | write!(f, "|")?; |
561 | }; | 599 | }; |
562 | 600 | ||
563 | let ret_display = sig.ret().into_displayable( | 601 | write!(f, " -> ")?; |
564 | f.db, | 602 | 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 { | 603 | } else { |
571 | write!(f, "{{closure}}")?; | 604 | write!(f, "{{closure}}")?; |
572 | } | 605 | } |
@@ -580,26 +613,27 @@ impl HirDisplay for Ty { | |||
580 | write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? | 613 | write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? |
581 | } | 614 | } |
582 | TypeParamProvenance::ArgumentImplTrait => { | 615 | TypeParamProvenance::ArgumentImplTrait => { |
583 | let substs = Substitution::type_params_for_generics(f.db, &generics); | 616 | let substs = generics.type_params_subst(f.db); |
584 | let bounds = f | 617 | let bounds = |
585 | .db | 618 | f.db.generic_predicates(id.parent) |
586 | .generic_predicates(id.parent) | 619 | .into_iter() |
587 | .into_iter() | 620 | .map(|pred| pred.clone().substitute(&Interner, &substs)) |
588 | .map(|pred| pred.clone().subst(&substs)) | 621 | .filter(|wc| match &wc.skip_binders() { |
589 | .filter(|wc| match &wc.skip_binders() { | 622 | WhereClause::Implemented(tr) => { |
590 | WhereClause::Implemented(tr) => tr.self_type_parameter() == self, | 623 | &tr.self_type_parameter(&Interner) == self |
591 | WhereClause::AliasEq(AliasEq { | 624 | } |
592 | alias: AliasTy::Projection(proj), | 625 | WhereClause::AliasEq(AliasEq { |
593 | ty: _, | 626 | alias: AliasTy::Projection(proj), |
594 | }) => proj.self_type_parameter() == self, | 627 | ty: _, |
595 | _ => false, | 628 | }) => &proj.self_type_parameter(&Interner) == self, |
596 | }) | 629 | _ => false, |
597 | .collect::<Vec<_>>(); | 630 | }) |
631 | .collect::<Vec<_>>(); | ||
598 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?; | 632 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?; |
599 | } | 633 | } |
600 | } | 634 | } |
601 | } | 635 | } |
602 | TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, | 636 | TyKind::BoundVar(idx) => idx.hir_fmt(f)?, |
603 | TyKind::Dyn(dyn_ty) => { | 637 | TyKind::Dyn(dyn_ty) => { |
604 | write_bounds_like_dyn_trait_with_prefix( | 638 | write_bounds_like_dyn_trait_with_prefix( |
605 | "dyn", | 639 | "dyn", |
@@ -617,15 +651,15 @@ impl HirDisplay for Ty { | |||
617 | let data = (*datas) | 651 | let data = (*datas) |
618 | .as_ref() | 652 | .as_ref() |
619 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 653 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
620 | let bounds = data.subst(&opaque_ty.substitution); | 654 | let bounds = data.substitute(&Interner, &opaque_ty.substitution); |
621 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 655 | write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?; |
622 | } | 656 | } |
623 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { | 657 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { |
624 | write!(f, "{{async block}}")?; | 658 | write!(f, "{{async block}}")?; |
625 | } | 659 | } |
626 | }; | 660 | }; |
627 | } | 661 | } |
628 | TyKind::Unknown => { | 662 | TyKind::Error => { |
629 | if f.display_target.is_source_code() { | 663 | if f.display_target.is_source_code() { |
630 | return Err(HirDisplayError::DisplaySourceCodeError( | 664 | return Err(HirDisplayError::DisplaySourceCodeError( |
631 | DisplaySourceCodeError::UnknownType, | 665 | DisplaySourceCodeError::UnknownType, |
@@ -634,6 +668,8 @@ impl HirDisplay for Ty { | |||
634 | write!(f, "{{unknown}}")?; | 668 | write!(f, "{{unknown}}")?; |
635 | } | 669 | } |
636 | TyKind::InferenceVar(..) => write!(f, "_")?, | 670 | TyKind::InferenceVar(..) => write!(f, "_")?, |
671 | TyKind::Generator(..) => write!(f, "{{generator}}")?, | ||
672 | TyKind::GeneratorWitness(..) => write!(f, "{{generator witness}}")?, | ||
637 | } | 673 | } |
638 | Ok(()) | 674 | Ok(()) |
639 | } | 675 | } |
@@ -652,10 +688,9 @@ impl HirDisplay for CallableSig { | |||
652 | } | 688 | } |
653 | write!(f, ")")?; | 689 | write!(f, ")")?; |
654 | let ret = self.ret(); | 690 | let ret = self.ret(); |
655 | if *ret != Ty::unit() { | 691 | if !ret.is_unit() { |
656 | let ret_display = | 692 | write!(f, " -> ")?; |
657 | ret.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); | 693 | ret.hir_fmt(f)?; |
658 | write!(f, " -> {}", ret_display)?; | ||
659 | } | 694 | } |
660 | Ok(()) | 695 | Ok(()) |
661 | } | 696 | } |
@@ -712,15 +747,17 @@ fn write_bounds_like_dyn_trait( | |||
712 | if !first { | 747 | if !first { |
713 | write!(f, " + ")?; | 748 | write!(f, " + ")?; |
714 | } | 749 | } |
715 | // We assume that the self type is $0 (i.e. the | 750 | // We assume that the self type is ^0.0 (i.e. the |
716 | // existential) here, which is the only thing that's | 751 | // existential) here, which is the only thing that's |
717 | // possible in actual Rust, and hence don't print it | 752 | // possible in actual Rust, and hence don't print it |
718 | write!(f, "{}", f.db.trait_data(trait_).name)?; | 753 | write!(f, "{}", f.db.trait_data(trait_).name)?; |
719 | if let [_, params @ ..] = &*trait_ref.substitution.0 { | 754 | if let [_, params @ ..] = &*trait_ref.substitution.as_slice(&Interner) { |
720 | if is_fn_trait { | 755 | if is_fn_trait { |
721 | if let Some(args) = params.first().and_then(|it| it.as_tuple()) { | 756 | if let Some(args) = |
757 | params.first().and_then(|it| it.assert_ty_ref(&Interner).as_tuple()) | ||
758 | { | ||
722 | write!(f, "(")?; | 759 | write!(f, "(")?; |
723 | f.write_joined(&*args.0, ", ")?; | 760 | f.write_joined(args.as_slice(&Interner), ", ")?; |
724 | write!(f, ")")?; | 761 | write!(f, ")")?; |
725 | } | 762 | } |
726 | } else if !params.is_empty() { | 763 | } else if !params.is_empty() { |
@@ -752,6 +789,10 @@ fn write_bounds_like_dyn_trait( | |||
752 | } | 789 | } |
753 | ty.hir_fmt(f)?; | 790 | ty.hir_fmt(f)?; |
754 | } | 791 | } |
792 | |||
793 | // FIXME implement these | ||
794 | WhereClause::LifetimeOutlives(_) => {} | ||
795 | WhereClause::TypeOutlives(_) => {} | ||
755 | } | 796 | } |
756 | first = false; | 797 | first = false; |
757 | } | 798 | } |
@@ -761,31 +802,29 @@ fn write_bounds_like_dyn_trait( | |||
761 | Ok(()) | 802 | Ok(()) |
762 | } | 803 | } |
763 | 804 | ||
764 | impl TraitRef { | 805 | 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> { | 806 | if f.should_truncate() { |
766 | if f.should_truncate() { | 807 | return write!(f, "{}", TYPE_HINT_TRUNCATION); |
767 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | 808 | } |
768 | } | ||
769 | 809 | ||
770 | self.substitution[0].hir_fmt(f)?; | 810 | tr.self_type_parameter(&Interner).hir_fmt(f)?; |
771 | if use_as { | 811 | if use_as { |
772 | write!(f, " as ")?; | 812 | write!(f, " as ")?; |
773 | } else { | 813 | } else { |
774 | write!(f, ": ")?; | 814 | write!(f, ": ")?; |
775 | } | 815 | } |
776 | write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?; | 816 | write!(f, "{}", f.db.trait_data(tr.hir_trait_id()).name)?; |
777 | if self.substitution.len() > 1 { | 817 | if tr.substitution.len(&Interner) > 1 { |
778 | write!(f, "<")?; | 818 | write!(f, "<")?; |
779 | f.write_joined(&self.substitution[1..], ", ")?; | 819 | f.write_joined(&tr.substitution.as_slice(&Interner)[1..], ", ")?; |
780 | write!(f, ">")?; | 820 | write!(f, ">")?; |
781 | } | ||
782 | Ok(()) | ||
783 | } | 821 | } |
822 | Ok(()) | ||
784 | } | 823 | } |
785 | 824 | ||
786 | impl HirDisplay for TraitRef { | 825 | impl HirDisplay for TraitRef { |
787 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 826 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
788 | self.hir_fmt_ext(f, false) | 827 | fmt_trait_ref(self, f, false) |
789 | } | 828 | } |
790 | } | 829 | } |
791 | 830 | ||
@@ -799,7 +838,7 @@ impl HirDisplay for WhereClause { | |||
799 | WhereClause::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, | 838 | WhereClause::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, |
800 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { | 839 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { |
801 | write!(f, "<")?; | 840 | write!(f, "<")?; |
802 | projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?; | 841 | fmt_trait_ref(&projection_ty.trait_ref(f.db), f, true)?; |
803 | write!( | 842 | write!( |
804 | f, | 843 | f, |
805 | ">::{} = ", | 844 | ">::{} = ", |
@@ -808,20 +847,44 @@ impl HirDisplay for WhereClause { | |||
808 | ty.hir_fmt(f)?; | 847 | ty.hir_fmt(f)?; |
809 | } | 848 | } |
810 | WhereClause::AliasEq(_) => write!(f, "{{error}}")?, | 849 | WhereClause::AliasEq(_) => write!(f, "{{error}}")?, |
850 | |||
851 | // FIXME implement these | ||
852 | WhereClause::TypeOutlives(..) => {} | ||
853 | WhereClause::LifetimeOutlives(..) => {} | ||
811 | } | 854 | } |
812 | Ok(()) | 855 | Ok(()) |
813 | } | 856 | } |
814 | } | 857 | } |
815 | 858 | ||
859 | impl HirDisplay for LifetimeOutlives { | ||
860 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
861 | self.a.hir_fmt(f)?; | ||
862 | write!(f, ": ")?; | ||
863 | self.b.hir_fmt(f) | ||
864 | } | ||
865 | } | ||
866 | |||
816 | impl HirDisplay for Lifetime { | 867 | impl HirDisplay for Lifetime { |
817 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 868 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
869 | self.interned().hir_fmt(f) | ||
870 | } | ||
871 | } | ||
872 | |||
873 | impl HirDisplay for LifetimeData { | ||
874 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
818 | match self { | 875 | match self { |
819 | Lifetime::Parameter(id) => { | 876 | LifetimeData::BoundVar(idx) => idx.hir_fmt(f), |
877 | LifetimeData::InferenceVar(_) => write!(f, "_"), | ||
878 | LifetimeData::Placeholder(idx) => { | ||
879 | let id = lt_from_placeholder_idx(f.db, *idx); | ||
820 | let generics = generics(f.db.upcast(), id.parent); | 880 | let generics = generics(f.db.upcast(), id.parent); |
821 | let param_data = &generics.params.lifetimes[id.local_id]; | 881 | let param_data = &generics.params.lifetimes[id.local_id]; |
822 | write!(f, "{}", ¶m_data.name) | 882 | write!(f, "{}", param_data.name) |
823 | } | 883 | } |
824 | Lifetime::Static => write!(f, "'static"), | 884 | LifetimeData::Static => write!(f, "'static"), |
885 | LifetimeData::Empty(_) => Ok(()), | ||
886 | LifetimeData::Erased => Ok(()), | ||
887 | LifetimeData::Phantom(_, _) => Ok(()), | ||
825 | } | 888 | } |
826 | } | 889 | } |
827 | } | 890 | } |
@@ -832,9 +895,11 @@ impl HirDisplay for DomainGoal { | |||
832 | DomainGoal::Holds(wc) => { | 895 | DomainGoal::Holds(wc) => { |
833 | write!(f, "Holds(")?; | 896 | write!(f, "Holds(")?; |
834 | wc.hir_fmt(f)?; | 897 | wc.hir_fmt(f)?; |
835 | write!(f, ")") | 898 | write!(f, ")")?; |
836 | } | 899 | } |
900 | _ => write!(f, "?")?, | ||
837 | } | 901 | } |
902 | Ok(()) | ||
838 | } | 903 | } |
839 | } | 904 | } |
840 | 905 | ||
@@ -1016,11 +1081,11 @@ impl HirDisplay for Path { | |||
1016 | } | 1081 | } |
1017 | } | 1082 | } |
1018 | 1083 | ||
1019 | impl HirDisplay for GenericArg { | 1084 | impl HirDisplay for hir_def::path::GenericArg { |
1020 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 1085 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
1021 | match self { | 1086 | match self { |
1022 | GenericArg::Type(ty) => ty.hir_fmt(f), | 1087 | hir_def::path::GenericArg::Type(ty) => ty.hir_fmt(f), |
1023 | GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name), | 1088 | hir_def::path::GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name), |
1024 | } | 1089 | } |
1025 | } | 1090 | } |
1026 | } | 1091 | } |