1 use rustc_data_structures
::fx
::FxHashSet
;
2 use rustc_errors
::{Applicability, ErrorReported, StashKey}
;
4 use rustc_hir
::def
::{DefKind, Res}
;
5 use rustc_hir
::def_id
::{DefId, LocalDefId}
;
6 use rustc_hir
::intravisit
;
7 use rustc_hir
::intravisit
::Visitor
;
8 use rustc_hir
::{HirId, Node}
;
9 use rustc_middle
::hir
::map
::Map
;
10 use rustc_middle
::ty
::subst
::{GenericArgKind, InternalSubsts}
;
11 use rustc_middle
::ty
::util
::IntTypeExt
;
12 use rustc_middle
::ty
::{self, DefIdTree, Ty, TyCtxt, TypeFoldable}
;
13 use rustc_span
::symbol
::Ident
;
14 use rustc_span
::{Span, DUMMY_SP}
;
17 use super::{bad_placeholder_type, is_suggestable_infer_ty}
;
19 /// Computes the relevant generic parameter for a potential generic const argument.
21 /// This should be called using the query `tcx.opt_const_param_of`.
22 pub(super) fn opt_const_param_of(tcx
: TyCtxt
<'_
>, def_id
: LocalDefId
) -> Option
<DefId
> {
24 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
);
26 if let Node
::AnonConst(_
) = tcx
.hir().get(hir_id
) {
27 let parent_node_id
= tcx
.hir().get_parent_node(hir_id
);
28 let parent_node
= tcx
.hir().get(parent_node_id
);
31 // This match arm is for when the def_id appears in a GAT whose
32 // path can't be resolved without typechecking e.g.
35 // type Assoc<const N: usize>;
36 // fn foo() -> Self::Assoc<3>;
39 // In the above code we would call this query with the def_id of 3 and
40 // the parent_node we match on would be the hir node for Self::Assoc<3>
42 // `Self::Assoc<3>` cant be resolved without typchecking here as we
43 // didnt write <Self as Foo>::Assoc<3>. If we did then another match
44 // arm would handle this.
46 // I believe this match arm is only needed for GAT but I am not 100% sure - BoxyUwU
47 Node
::Ty(hir_ty @ Ty { kind: TyKind::Path(QPath::TypeRelative(_, segment)), .. }
) => {
48 // Find the Item containing the associated type so we can create an ItemCtxt.
49 // Using the ItemCtxt convert the HIR for the unresolved assoc type into a
50 // ty which is a fully resolved projection.
51 // For the code example above, this would mean converting Self::Assoc<3>
52 // into a ty::Projection(<Self as Foo>::Assoc<3>)
56 .filter(|(_
, node
)| matches
!(node
, Node
::Item(_
)))
60 let item_did
= tcx
.hir().local_def_id(item_hir_id
).to_def_id();
61 let item_ctxt
= &ItemCtxt
::new(tcx
, item_did
) as &dyn crate::astconv
::AstConv
<'_
>;
62 let ty
= item_ctxt
.ast_ty_to_ty(hir_ty
);
64 // Iterate through the generics of the projection to find the one that corresponds to
65 // the def_id that this query was called with. We filter to only const args here as a
66 // precaution for if it's ever allowed to elide lifetimes in GAT's. It currently isn't
67 // but it can't hurt to be safe ^^
68 if let ty
::Projection(projection
) = ty
.kind() {
69 let generics
= tcx
.generics_of(projection
.item_def_id
);
71 let arg_index
= segment
76 .filter(|arg
| arg
.is_const())
77 .position(|arg
| arg
.id() == hir_id
)
80 bug
!("no arg matching AnonConst in segment");
86 .filter(|param
| matches
!(param
.kind
, ty
::GenericParamDefKind
::Const { .. }
))
88 .map(|param
| param
.def_id
);
91 // I dont think it's possible to reach this but I'm not 100% sure - BoxyUwU
92 tcx
.sess
.delay_span_bug(
94 "unexpected non-GAT usage of an anon const",
100 ExprKind
::MethodCall(segment
, ..) | ExprKind
::Path(QPath
::TypeRelative(_
, segment
)),
103 let body_owner
= tcx
.hir().local_def_id(tcx
.hir().enclosing_body_owner(hir_id
));
104 let tables
= tcx
.typeck(body_owner
);
105 // This may fail in case the method/path does not actually exist.
106 // As there is no relevant param for `def_id`, we simply return
108 let type_dependent_def
= tables
.type_dependent_def_id(parent_node_id
)?
;
114 .filter(|arg
| arg
.is_const())
115 .position(|arg
| arg
.id() == hir_id
)
118 bug
!("no arg matching AnonConst in segment");
121 tcx
.generics_of(type_dependent_def
)
124 .filter(|param
| matches
!(param
.kind
, ty
::GenericParamDefKind
::Const { .. }
))
126 .map(|param
| param
.def_id
)
129 Node
::Ty(&Ty { kind: TyKind::Path(_), .. }
)
130 | Node
::Expr(&Expr { kind: ExprKind::Path(_) | ExprKind::Struct(..), .. }
)
133 let path
= match parent_node
{
134 Node
::Ty(&Ty { kind: TyKind::Path(QPath::Resolved(_, path)), .. }
)
135 | Node
::TraitRef(&TraitRef { path, .. }
) => &*path
,
138 ExprKind
::Path(QPath
::Resolved(_
, path
))
139 | ExprKind
::Struct(&QPath
::Resolved(_
, path
), ..),
143 tcx
.hir().local_def_id(tcx
.hir().enclosing_body_owner(hir_id
));
144 let _tables
= tcx
.typeck(body_owner
);
148 if let Some(path
) = get_path_containing_arg_in_pat(pat
, hir_id
) {
151 tcx
.sess
.delay_span_bug(
152 tcx
.def_span(def_id
),
154 "unable to find const parent for {} in pat {:?}",
162 tcx
.sess
.delay_span_bug(
163 tcx
.def_span(def_id
),
164 &format
!("unexpected const parent path {:?}", parent_node
),
170 // We've encountered an `AnonConst` in some path, so we need to
171 // figure out which generic parameter it corresponds to and return
172 // the relevant type.
173 let (arg_index
, segment
) = path
176 .filter_map(|seg
| seg
.args
.map(|args
| (args
.args
, seg
)))
177 .find_map(|(args
, seg
)| {
179 .filter(|arg
| arg
.is_const())
180 .position(|arg
| arg
.id() == hir_id
)
181 .map(|index
| (index
, seg
))
184 bug
!("no arg matching AnonConst in path");
187 // Try to use the segment resolution if it is valid, otherwise we
188 // default to the path resolution.
189 let res
= segment
.res
.filter(|&r
| r
!= Res
::Err
).unwrap_or(path
.res
);
190 let generics
= match res
{
191 Res
::Def(DefKind
::Ctor(..), def_id
) => {
192 tcx
.generics_of(tcx
.parent(def_id
).unwrap())
194 // Other `DefKind`s don't have generics and would ICE when calling
205 | DefKind
::TraitAlias
209 | DefKind
::AssocConst
212 ) => tcx
.generics_of(def_id
),
214 tcx
.sess
.delay_span_bug(tcx
.def_span(def_id
), "anon const with Res::Err");
218 // If the user tries to specify generics on a type that does not take them,
219 // e.g. `usize<T>`, we may hit this branch, in which case we treat it as if
220 // no arguments have been passed. An error should already have been emitted.
221 tcx
.sess
.delay_span_bug(
222 tcx
.def_span(def_id
),
223 &format
!("unexpected anon const res {:?} in path: {:?}", res
, path
),
232 .filter(|param
| matches
!(param
.kind
, ty
::GenericParamDefKind
::Const { .. }
))
234 .map(|param
| param
.def_id
)
243 fn get_path_containing_arg_in_pat
<'hir
>(
244 pat
: &'hir hir
::Pat
<'hir
>,
246 ) -> Option
<&'hir hir
::Path
<'hir
>> {
249 let is_arg_in_path
= |p
: &hir
::Path
<'_
>| {
252 .filter_map(|seg
| seg
.args
)
253 .flat_map(|args
| args
.args
)
254 .any(|arg
| arg
.id() == arg_id
)
256 let mut arg_path
= None
;
257 pat
.walk(|pat
| match pat
.kind
{
258 PatKind
::Struct(QPath
::Resolved(_
, path
), _
, _
)
259 | PatKind
::TupleStruct(QPath
::Resolved(_
, path
), _
, _
)
260 | PatKind
::Path(QPath
::Resolved(_
, path
))
261 if is_arg_in_path(path
) =>
263 arg_path
= Some(path
);
271 pub(super) fn type_of(tcx
: TyCtxt
<'_
>, def_id
: DefId
) -> Ty
<'_
> {
272 let def_id
= def_id
.expect_local();
275 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
);
277 let icx
= ItemCtxt
::new(tcx
, def_id
.to_def_id());
279 match tcx
.hir().get(hir_id
) {
280 Node
::TraitItem(item
) => match item
.kind
{
281 TraitItemKind
::Fn(..) => {
282 let substs
= InternalSubsts
::identity_for_item(tcx
, def_id
.to_def_id());
283 tcx
.mk_fn_def(def_id
.to_def_id(), substs
)
285 TraitItemKind
::Const(ref ty
, body_id
) => body_id
286 .and_then(|body_id
| {
287 if is_suggestable_infer_ty(ty
) {
288 Some(infer_placeholder_type(tcx
, def_id
, body_id
, ty
.span
, item
.ident
))
293 .unwrap_or_else(|| icx
.to_ty(ty
)),
294 TraitItemKind
::Type(_
, Some(ref ty
)) => icx
.to_ty(ty
),
295 TraitItemKind
::Type(_
, None
) => {
296 span_bug
!(item
.span
, "associated type missing default");
300 Node
::ImplItem(item
) => match item
.kind
{
301 ImplItemKind
::Fn(..) => {
302 let substs
= InternalSubsts
::identity_for_item(tcx
, def_id
.to_def_id());
303 tcx
.mk_fn_def(def_id
.to_def_id(), substs
)
305 ImplItemKind
::Const(ref ty
, body_id
) => {
306 if is_suggestable_infer_ty(ty
) {
307 infer_placeholder_type(tcx
, def_id
, body_id
, ty
.span
, item
.ident
)
312 ImplItemKind
::TyAlias(ref ty
) => {
313 if tcx
.impl_trait_ref(tcx
.hir().get_parent_did(hir_id
).to_def_id()).is_none() {
314 check_feature_inherent_assoc_ty(tcx
, item
.span
);
321 Node
::Item(item
) => {
323 ItemKind
::Static(ref ty
, .., body_id
) | ItemKind
::Const(ref ty
, body_id
) => {
324 if is_suggestable_infer_ty(ty
) {
325 infer_placeholder_type(tcx
, def_id
, body_id
, ty
.span
, item
.ident
)
330 ItemKind
::TyAlias(ref self_ty
, _
)
331 | ItemKind
::Impl(hir
::Impl { ref self_ty, .. }
) => icx
.to_ty(self_ty
),
332 ItemKind
::Fn(..) => {
333 let substs
= InternalSubsts
::identity_for_item(tcx
, def_id
.to_def_id());
334 tcx
.mk_fn_def(def_id
.to_def_id(), substs
)
336 ItemKind
::Enum(..) | ItemKind
::Struct(..) | ItemKind
::Union(..) => {
337 let def
= tcx
.adt_def(def_id
);
338 let substs
= InternalSubsts
::identity_for_item(tcx
, def_id
.to_def_id());
339 tcx
.mk_adt(def
, substs
)
341 ItemKind
::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::Binding, .. }
) => {
342 let_position_impl_trait_type(tcx
, def_id
)
344 ItemKind
::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }
) => {
345 find_opaque_ty_constraints(tcx
, def_id
)
347 // Opaque types desugared from `impl Trait`.
348 ItemKind
::OpaqueTy(OpaqueTy { impl_trait_fn: Some(owner), .. }
) => {
349 let concrete_ty
= tcx
350 .mir_borrowck(owner
.expect_local())
351 .concrete_opaque_types
352 .get_by(|(key
, _
)| key
.def_id
== def_id
.to_def_id())
353 .map(|concrete_ty
| *concrete_ty
)
355 tcx
.sess
.delay_span_bug(
358 "owner {:?} has no opaque type for {:?} in its typeck results",
362 if let Some(ErrorReported
) =
363 tcx
.typeck(owner
.expect_local()).tainted_by_errors
366 // owner fn prevented us from populating
367 // the `concrete_opaque_types` table.
370 // We failed to resolve the opaque type or it
371 // resolves to itself. Return the non-revealed
372 // type, which should result in E0720.
375 InternalSubsts
::identity_for_item(tcx
, def_id
.to_def_id()),
379 debug
!("concrete_ty = {:?}", concrete_ty
);
383 | ItemKind
::TraitAlias(..)
385 | ItemKind
::ForeignMod { .. }
386 | ItemKind
::GlobalAsm(..)
387 | ItemKind
::ExternCrate(..)
388 | ItemKind
::Use(..) => {
391 "compute_type_of_item: unexpected item type: {:?}",
398 Node
::ForeignItem(foreign_item
) => match foreign_item
.kind
{
399 ForeignItemKind
::Fn(..) => {
400 let substs
= InternalSubsts
::identity_for_item(tcx
, def_id
.to_def_id());
401 tcx
.mk_fn_def(def_id
.to_def_id(), substs
)
403 ForeignItemKind
::Static(ref t
, _
) => icx
.to_ty(t
),
404 ForeignItemKind
::Type
=> tcx
.mk_foreign(def_id
.to_def_id()),
407 Node
::Ctor(&ref def
) | Node
::Variant(Variant { data: ref def, .. }
) => match *def
{
408 VariantData
::Unit(..) | VariantData
::Struct(..) => {
409 tcx
.type_of(tcx
.hir().get_parent_did(hir_id
).to_def_id())
411 VariantData
::Tuple(..) => {
412 let substs
= InternalSubsts
::identity_for_item(tcx
, def_id
.to_def_id());
413 tcx
.mk_fn_def(def_id
.to_def_id(), substs
)
417 Node
::Field(field
) => icx
.to_ty(&field
.ty
),
419 Node
::Expr(&Expr { kind: ExprKind::Closure(.., gen), .. }
) => {
420 let substs
= InternalSubsts
::identity_for_item(tcx
, def_id
.to_def_id());
421 if let Some(movability
) = gen
{
422 tcx
.mk_generator(def_id
.to_def_id(), substs
, movability
)
424 tcx
.mk_closure(def_id
.to_def_id(), substs
)
428 Node
::AnonConst(_
) => {
429 if let Some(param
) = tcx
.opt_const_param_of(def_id
) {
430 // We defer to `type_of` of the corresponding parameter
431 // for generic arguments.
432 return tcx
.type_of(param
);
435 let parent_node
= tcx
.hir().get(tcx
.hir().get_parent_node(hir_id
));
437 Node
::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. }
)
438 | Node
::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }
)
439 if constant
.hir_id
== hir_id
=>
443 Node
::Ty(&Ty { kind: TyKind::Typeof(ref e), .. }
) if e
.hir_id
== hir_id
=> {
444 tcx
.typeck(def_id
).node_type(e
.hir_id
)
447 Node
::Expr(&Expr { kind: ExprKind::ConstBlock(ref anon_const), .. }
)
448 if anon_const
.hir_id
== hir_id
=>
450 tcx
.typeck(def_id
).node_type(anon_const
.hir_id
)
453 Node
::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }
)
454 | Node
::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }
)
455 if asm
.operands
.iter().any(|(op
, _op_sp
)| match op
{
456 hir
::InlineAsmOperand
::Const { anon_const }
=> anon_const
.hir_id
== hir_id
,
460 tcx
.typeck(def_id
).node_type(hir_id
)
463 Node
::Variant(Variant { disr_expr: Some(ref e), .. }
) if e
.hir_id
== hir_id
=> tcx
464 .adt_def(tcx
.hir().get_parent_did(hir_id
).to_def_id())
469 Node
::GenericParam(&GenericParam
{
470 hir_id
: param_hir_id
,
471 kind
: GenericParamKind
::Const { default: Some(ct), .. }
,
473 }) if ct
.hir_id
== hir_id
=> tcx
.type_of(tcx
.hir().local_def_id(param_hir_id
)),
475 x
=> tcx
.ty_error_with_message(
477 &format
!("unexpected const parent in type_of_def_id(): {:?}", x
),
482 Node
::GenericParam(param
) => match ¶m
.kind
{
483 GenericParamKind
::Type { default: Some(ty), .. }
484 | GenericParamKind
::Const { ty, .. }
=> icx
.to_ty(ty
),
485 x
=> bug
!("unexpected non-type Node::GenericParam: {:?}", x
),
489 bug
!("unexpected sort of node in type_of_def_id(): {:?}", x
);
494 fn find_opaque_ty_constraints(tcx
: TyCtxt
<'_
>, def_id
: LocalDefId
) -> Ty
<'_
> {
495 use rustc_hir
::{Expr, ImplItem, Item, TraitItem}
;
497 debug
!("find_opaque_ty_constraints({:?})", def_id
);
499 struct ConstraintLocator
<'tcx
> {
502 // (first found type span, actual type)
503 found
: Option
<(Span
, Ty
<'tcx
>)>,
506 impl ConstraintLocator
<'_
> {
507 fn check(&mut self, def_id
: LocalDefId
) {
508 // Don't try to check items that cannot possibly constrain the type.
509 if !self.tcx
.has_typeck_results(def_id
) {
511 "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`: no typeck results",
516 // Calling `mir_borrowck` can lead to cycle errors through
517 // const-checking, avoid calling it if we don't have to.
521 .concrete_opaque_types
522 .get_by(|(key
, _
)| key
.def_id
== self.def_id
)
526 "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`",
531 // Use borrowck to get the type with unerased regions.
532 let concrete_opaque_types
= &self.tcx
.mir_borrowck(def_id
).concrete_opaque_types
;
533 if let Some((opaque_type_key
, concrete_type
)) =
534 concrete_opaque_types
.iter().find(|(key
, _
)| key
.def_id
== self.def_id
)
537 "find_opaque_ty_constraints: found constraint for `{:?}` at `{:?}`: {:?}",
538 self.def_id
, def_id
, concrete_type
,
541 // FIXME(oli-obk): trace the actual span from inference to improve errors.
542 let span
= self.tcx
.def_span(def_id
);
544 // HACK(eddyb) this check shouldn't be needed, as `wfcheck`
545 // performs the same checks, in theory, but I've kept it here
546 // using `delay_span_bug`, just in case `wfcheck` slips up.
547 let opaque_generics
= self.tcx
.generics_of(self.def_id
);
548 let mut used_params
: FxHashSet
<_
> = FxHashSet
::default();
549 for (i
, arg
) in opaque_type_key
.substs
.iter().enumerate() {
550 let arg_is_param
= match arg
.unpack() {
551 GenericArgKind
::Type(ty
) => matches
!(ty
.kind(), ty
::Param(_
)),
552 GenericArgKind
::Lifetime(lt
) => {
553 matches
!(lt
, ty
::ReEarlyBound(_
) | ty
::ReFree(_
))
555 GenericArgKind
::Const(ct
) => matches
!(ct
.val
, ty
::ConstKind
::Param(_
)),
559 if !used_params
.insert(arg
) {
560 // There was already an entry for `arg`, meaning a generic parameter
562 self.tcx
.sess
.delay_span_bug(
565 "defining opaque type use restricts opaque \
566 type by using the generic parameter `{}` twice",
572 let param
= opaque_generics
.param_at(i
, self.tcx
);
573 self.tcx
.sess
.delay_span_bug(
576 "defining opaque type use does not fully define opaque type: \
577 generic parameter `{}` is specified as concrete {} `{}`",
586 if let Some((prev_span
, prev_ty
)) = self.found
{
587 if *concrete_type
!= prev_ty
{
588 debug
!("find_opaque_ty_constraints: span={:?}", span
);
589 // Found different concrete types for the opaque type.
590 let mut err
= self.tcx
.sess
.struct_span_err(
592 "concrete type differs from previous defining opaque type use",
596 format
!("expected `{}`, got `{}`", prev_ty
, concrete_type
),
598 err
.span_note(prev_span
, "previous use here");
602 self.found
= Some((span
, concrete_type
));
606 "find_opaque_ty_constraints: no constraint for `{:?}` at `{:?}`",
613 impl<'tcx
> intravisit
::Visitor
<'tcx
> for ConstraintLocator
<'tcx
> {
614 type Map
= Map
<'tcx
>;
616 fn nested_visit_map(&mut self) -> intravisit
::NestedVisitorMap
<Self::Map
> {
617 intravisit
::NestedVisitorMap
::All(self.tcx
.hir())
619 fn visit_expr(&mut self, ex
: &'tcx Expr
<'tcx
>) {
620 if let hir
::ExprKind
::Closure(..) = ex
.kind
{
621 let def_id
= self.tcx
.hir().local_def_id(ex
.hir_id
);
624 intravisit
::walk_expr(self, ex
);
626 fn visit_item(&mut self, it
: &'tcx Item
<'tcx
>) {
627 debug
!("find_existential_constraints: visiting {:?}", it
);
628 // The opaque type itself or its children are not within its reveal scope.
629 if it
.def_id
.to_def_id() != self.def_id
{
630 self.check(it
.def_id
);
631 intravisit
::walk_item(self, it
);
634 fn visit_impl_item(&mut self, it
: &'tcx ImplItem
<'tcx
>) {
635 debug
!("find_existential_constraints: visiting {:?}", it
);
636 // The opaque type itself or its children are not within its reveal scope.
637 if it
.def_id
.to_def_id() != self.def_id
{
638 self.check(it
.def_id
);
639 intravisit
::walk_impl_item(self, it
);
642 fn visit_trait_item(&mut self, it
: &'tcx TraitItem
<'tcx
>) {
643 debug
!("find_existential_constraints: visiting {:?}", it
);
644 self.check(it
.def_id
);
645 intravisit
::walk_trait_item(self, it
);
649 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
);
650 let scope
= tcx
.hir().get_defining_scope(hir_id
);
651 let mut locator
= ConstraintLocator { def_id: def_id.to_def_id(), tcx, found: None }
;
653 debug
!("find_opaque_ty_constraints: scope={:?}", scope
);
655 if scope
== hir
::CRATE_HIR_ID
{
656 intravisit
::walk_crate(&mut locator
, tcx
.hir().krate());
658 debug
!("find_opaque_ty_constraints: scope={:?}", tcx
.hir().get(scope
));
659 match tcx
.hir().get(scope
) {
660 // We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods
661 // This allows our visitor to process the defining item itself, causing
662 // it to pick up any 'sibling' defining uses.
664 // For example, this code:
667 // type Blah = impl Debug;
668 // let my_closure = || -> Blah { true };
672 // requires us to explicitly process `foo()` in order
673 // to notice the defining usage of `Blah`.
674 Node
::Item(ref it
) => locator
.visit_item(it
),
675 Node
::ImplItem(ref it
) => locator
.visit_impl_item(it
),
676 Node
::TraitItem(ref it
) => locator
.visit_trait_item(it
),
677 other
=> bug
!("{:?} is not a valid scope for an opaque type item", other
),
681 match locator
.found
{
684 let span
= tcx
.def_span(def_id
);
685 tcx
.sess
.span_err(span
, "could not find defining uses");
691 /// Retrieve the inferred concrete type for let position impl trait.
693 /// This is different to other kinds of impl trait because:
695 /// 1. We know which function contains the defining use (the function that
696 /// contains the let statement)
697 /// 2. We do not currently allow (free) lifetimes in the return type. `let`
698 /// statements in some statically unreachable code are removed from the MIR
699 /// by the time we borrow check, and it's not clear how we should handle
701 fn let_position_impl_trait_type(tcx
: TyCtxt
<'_
>, opaque_ty_id
: LocalDefId
) -> Ty
<'_
> {
702 let scope
= tcx
.hir().get_defining_scope(tcx
.hir().local_def_id_to_hir_id(opaque_ty_id
));
703 let scope_def_id
= tcx
.hir().local_def_id(scope
);
705 let opaque_ty_def_id
= opaque_ty_id
.to_def_id();
707 let owner_typeck_results
= tcx
.typeck(scope_def_id
);
708 let concrete_ty
= owner_typeck_results
709 .concrete_opaque_types
710 .get_by(|(key
, _
)| key
.def_id
== opaque_ty_def_id
)
711 .map(|concrete_ty
| *concrete_ty
)
713 tcx
.sess
.delay_span_bug(
716 "owner {:?} has no opaque type for {:?} in its typeck results",
717 scope_def_id
, opaque_ty_id
720 if let Some(ErrorReported
) = owner_typeck_results
.tainted_by_errors
{
721 // Some error in the owner fn prevented us from populating the
722 // `concrete_opaque_types` table.
725 // We failed to resolve the opaque type or it resolves to
726 // itself. Return the non-revealed type, which should result in
730 InternalSubsts
::identity_for_item(tcx
, opaque_ty_def_id
),
734 debug
!("concrete_ty = {:?}", concrete_ty
);
735 if concrete_ty
.has_erased_regions() {
736 // FIXME(impl_trait_in_bindings) Handle this case.
738 tcx
.hir().span(tcx
.hir().local_def_id_to_hir_id(opaque_ty_id
)),
739 "lifetimes in impl Trait types in bindings are not currently supported",
745 fn infer_placeholder_type(
748 body_id
: hir
::BodyId
,
752 let ty
= tcx
.diagnostic_only_typeck(def_id
).node_type(body_id
.hir_id
);
754 // If this came from a free `const` or `static mut?` item,
755 // then the user may have written e.g. `const A = 42;`.
756 // In this case, the parser has stashed a diagnostic for
757 // us to improve in typeck so we do that now.
758 match tcx
.sess
.diagnostic().steal_diagnostic(span
, StashKey
::ItemNoType
) {
760 // The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
761 // We are typeck and have the real type, so remove that and suggest the actual type.
762 err
.suggestions
.clear();
765 "provide a type for the item",
766 format
!("{}: {}", item_ident
, ty
),
767 Applicability
::MachineApplicable
,
769 .emit_unless(ty
.references_error());
772 let mut diag
= bad_placeholder_type(tcx
, vec
![span
]);
774 if !ty
.references_error() {
775 diag
.span_suggestion(
777 "replace with the correct type",
779 Applicability
::MaybeIncorrect
,
787 // Typeck doesn't expect erased regions to be returned from `type_of`.
788 tcx
.fold_regions(ty
, &mut false, |r
, _
| match r
{
789 ty
::ReErased
=> tcx
.lifetimes
.re_static
,
794 fn check_feature_inherent_assoc_ty(tcx
: TyCtxt
<'_
>, span
: Span
) {
795 if !tcx
.features().inherent_associated_types
{
796 use rustc_session
::parse
::feature_err
;
797 use rustc_span
::symbol
::sym
;
799 &tcx
.sess
.parse_sess
,
800 sym
::inherent_associated_types
,
802 "inherent associated types are unstable",