1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
5 // GCC is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3, or (at your option) any later
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
19 #include "rust-hir-type-check-implitem.h"
20 #include "rust-diagnostics.h"
21 #include "rust-hir-type-check-base.h"
22 #include "rust-hir-type-check-type.h"
23 #include "rust-hir-type-check-expr.h"
24 #include "rust-hir-type-check-pattern.h"
25 #include "rust-type-util.h"
26 #include "rust-tyty.h"
31 TypeCheckTopLevelExternItem::TypeCheckTopLevelExternItem (
32 const HIR::ExternBlock
&parent
)
33 : TypeCheckBase (), parent (parent
)
37 TypeCheckTopLevelExternItem::Resolve (HIR::ExternalItem
*item
,
38 const HIR::ExternBlock
&parent
)
40 // is it already resolved?
41 auto context
= TypeCheckContext::get ();
42 TyTy::BaseType
*resolved
= nullptr;
44 = context
->lookup_type (item
->get_mappings ().get_hirid (), &resolved
);
48 TypeCheckTopLevelExternItem
resolver (parent
);
49 item
->accept_vis (resolver
);
50 return resolver
.resolved
;
54 TypeCheckTopLevelExternItem::visit (HIR::ExternalStaticItem
&item
)
56 TyTy::BaseType
*actual_type
57 = TypeCheckType::Resolve (item
.get_item_type ().get ());
59 context
->insert_type (item
.get_mappings (), actual_type
);
60 resolved
= actual_type
;
64 TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem
&function
)
66 auto binder_pin
= context
->push_clean_lifetime_resolver ();
68 std::vector
<TyTy::SubstitutionParamMapping
> substitutions
;
69 if (function
.has_generics ())
71 for (auto &generic_param
: function
.get_generic_params ())
73 switch (generic_param
.get ()->get_kind ())
75 case HIR::GenericParam::GenericKind::LIFETIME
:
76 context
->intern_and_insert_lifetime (
77 static_cast<HIR::LifetimeParam
&> (*generic_param
)
79 // TODO: handle bounds
81 case HIR::GenericParam::GenericKind::CONST
:
82 // FIXME: Skipping Lifetime and Const completely until better
86 case HIR::GenericParam::GenericKind::TYPE
: {
88 = TypeResolveGenericParam::Resolve (generic_param
.get ());
89 context
->insert_type (generic_param
->get_mappings (),
92 substitutions
.push_back (TyTy::SubstitutionParamMapping (
93 static_cast<HIR::TypeParam
&> (*generic_param
), param_type
));
100 TyTy::RegionConstraints region_constraints
;
101 if (function
.has_where_clause ())
103 for (auto &where_clause_item
: function
.get_where_clause ().get_items ())
105 ResolveWhereClauseItem::Resolve (*where_clause_item
.get (),
110 TyTy::BaseType
*ret_type
= nullptr;
111 if (!function
.has_return_type ())
113 = TyTy::TupleType::get_unit_type (function
.get_mappings ().get_hirid ());
117 = TypeCheckType::Resolve (function
.get_return_type ().get ());
118 if (resolved
== nullptr)
120 rust_error_at (function
.get_locus (),
121 "failed to resolve return type");
125 ret_type
= resolved
->clone ();
127 function
.get_return_type ()->get_mappings ().get_hirid ());
130 std::vector
<std::pair
<HIR::Pattern
*, TyTy::BaseType
*> > params
;
131 for (auto ¶m
: function
.get_function_params ())
133 // get the name as well required for later on
134 auto param_tyty
= TypeCheckType::Resolve (param
.get_type ().get ());
136 // these are implicit mappings and not used
137 auto crate_num
= mappings
->get_current_crate ();
138 Analysis::NodeMapping
mapping (crate_num
, mappings
->get_next_node_id (),
139 mappings
->get_next_hir_id (crate_num
),
140 UNKNOWN_LOCAL_DEFID
);
142 HIR::IdentifierPattern
*param_pattern
143 = new HIR::IdentifierPattern (mapping
, param
.get_param_name (),
144 UNDEF_LOCATION
, false, Mutability::Imm
,
145 std::unique_ptr
<HIR::Pattern
> (nullptr));
148 std::pair
<HIR::Pattern
*, TyTy::BaseType
*> (param_pattern
,
151 context
->insert_type (param
.get_mappings (), param_tyty
);
153 // FIXME do we need error checking for patterns here?
154 // see https://github.com/Rust-GCC/gccrs/issues/995
157 uint8_t flags
= TyTy::FnType::FNTYPE_IS_EXTERN_FLAG
;
158 if (function
.is_variadic ())
160 flags
|= TyTy::FnType::FNTYPE_IS_VARADIC_FLAG
;
161 if (parent
.get_abi () != Rust::ABI::C
)
164 function
.get_locus (), ErrorCode::E0045
,
165 "C-variadic function must have C or cdecl calling convention");
170 CanonicalPath::new_seg (function
.get_mappings ().get_nodeid (),
171 function
.get_item_name ().as_string ()),
172 function
.get_locus ()};
174 auto fnType
= new TyTy::FnType (
175 function
.get_mappings ().get_hirid (),
176 function
.get_mappings ().get_defid (),
177 function
.get_item_name ().as_string (), ident
, flags
, parent
.get_abi (),
178 std::move (params
), ret_type
, std::move (substitutions
),
179 TyTy::SubstitutionArgumentMappings::empty (
180 context
->get_lifetime_resolver ().get_num_bound_regions ()),
183 context
->insert_type (function
.get_mappings (), fnType
);
188 TypeCheckTopLevelExternItem::visit (HIR::ExternalTypeItem
&type
)
190 rust_sorry_at (type
.get_locus (), "extern types are not supported yet");
191 // auto binder_pin = context->push_clean_lifetime_resolver ();
193 // std::vector<TyTy::SubstitutionParamMapping> substitutions;
194 // if (function.has_generics ())
196 // for (auto &generic_param : function.get_generic_params ())
198 // switch (generic_param.get ()->get_kind ())
200 // case HIR::GenericParam::GenericKind::LIFETIME:
201 // context->intern_and_insert_lifetime (
202 // static_cast<HIR::LifetimeParam &> (*generic_param)
203 // .get_lifetime ());
204 // // TODO: handle bounds
206 // case HIR::GenericParam::GenericKind::CONST:
207 // // FIXME: Skipping Lifetime and Const completely until better
211 // case HIR::GenericParam::GenericKind::TYPE: {
213 // = TypeResolveGenericParam::Resolve (generic_param.get ());
214 // context->insert_type (generic_param->get_mappings (),
217 // substitutions.push_back (TyTy::SubstitutionParamMapping (
218 // static_cast<HIR::TypeParam &> (*generic_param), param_type));
225 // TyTy::RegionConstraints region_constraints;
226 // if (function.has_where_clause ())
228 // for (auto &where_clause_item : function.get_where_clause ().get_items
231 // ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
232 // region_constraints);
236 // TyTy::BaseType *ret_type = nullptr;
237 // if (!function.has_return_type ())
239 // = TyTy::TupleType::get_unit_type (function.get_mappings ().get_hirid
244 // = TypeCheckType::Resolve (function.get_return_type ().get ());
245 // if (resolved == nullptr)
247 // rust_error_at (function.get_locus (),
248 // "failed to resolve return type");
252 // ret_type = resolved->clone ();
253 // ret_type->set_ref (
254 // function.get_return_type ()->get_mappings ().get_hirid ());
257 // std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
258 // for (auto ¶m : function.get_function_params ())
260 // // get the name as well required for later on
261 // auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
263 // // these are implicit mappings and not used
264 // auto crate_num = mappings->get_current_crate ();
265 // Analysis::NodeMapping mapping (crate_num, mappings->get_next_node_id
267 // mappings->get_next_hir_id (crate_num),
268 // UNKNOWN_LOCAL_DEFID);
270 // HIR::IdentifierPattern *param_pattern
271 // = new HIR::IdentifierPattern (mapping, param.get_param_name (),
272 // UNDEF_LOCATION, false, Mutability::Imm,
273 // std::unique_ptr<HIR::Pattern> (nullptr));
275 // params.push_back (
276 // std::pair<HIR::Pattern *, TyTy::BaseType *> (param_pattern,
279 // context->insert_type (param.get_mappings (), param_tyty);
281 // // FIXME do we need error checking for patterns here?
282 // // see https://github.com/Rust-GCC/gccrs/issues/995
285 // uint8_t flags = TyTy::FnType::FNTYPE_IS_EXTERN_FLAG;
286 // if (function.is_variadic ())
288 // flags |= TyTy::FnType::FNTYPE_IS_VARADIC_FLAG;
289 // if (parent.get_abi () != Rust::ABI::C)
292 // function.get_locus (), ErrorCode::E0045,
293 // "C-variadic function must have C or cdecl calling convention");
298 // CanonicalPath::new_seg (function.get_mappings ().get_nodeid (),
299 // function.get_item_name ().as_string ()),
300 // function.get_locus ()};
302 // auto fnType = new TyTy::FnType (
303 // function.get_mappings ().get_hirid (),
304 // function.get_mappings ().get_defid (),
305 // function.get_item_name ().as_string (), ident, flags, parent.get_abi (),
306 // std::move (params), ret_type, std::move (substitutions),
307 // TyTy::SubstitutionArgumentMappings::empty (
308 // context->get_lifetime_resolver ().get_num_bound_regions ()),
309 // region_constraints);
311 // context->insert_type (function.get_mappings (), fnType);
312 // resolved = fnType;
315 TypeCheckImplItem::TypeCheckImplItem (
316 HIR::ImplBlock
*parent
, TyTy::BaseType
*self
,
317 std::vector
<TyTy::SubstitutionParamMapping
> substitutions
)
318 : TypeCheckBase (), parent (parent
), self (self
),
319 substitutions (substitutions
)
323 TypeCheckImplItem::Resolve (
324 HIR::ImplBlock
*parent
, HIR::ImplItem
*item
, TyTy::BaseType
*self
,
325 std::vector
<TyTy::SubstitutionParamMapping
> substitutions
)
327 // is it already resolved?
328 auto context
= TypeCheckContext::get ();
329 TyTy::BaseType
*resolved
= nullptr;
330 bool already_resolved
331 = context
->lookup_type (item
->get_impl_mappings ().get_hirid (), &resolved
);
332 if (already_resolved
)
336 TypeCheckImplItem
resolver (parent
, self
, substitutions
);
337 item
->accept_vis (resolver
);
338 return resolver
.result
;
342 TypeCheckImplItem::visit (HIR::Function
&function
)
344 auto binder_pin
= context
->push_lifetime_binder ();
346 if (function
.has_generics ())
347 resolve_generic_params (function
.get_generic_params (), substitutions
);
349 TyTy::RegionConstraints region_constraints
;
350 for (auto &where_clause_item
: function
.get_where_clause ().get_items ())
352 ResolveWhereClauseItem::Resolve (*where_clause_item
.get (),
356 TyTy::BaseType
*ret_type
= nullptr;
357 if (!function
.has_function_return_type ())
359 = TyTy::TupleType::get_unit_type (function
.get_mappings ().get_hirid ());
363 = TypeCheckType::Resolve (function
.get_return_type ().get ());
364 if (resolved
== nullptr)
366 rust_error_at (function
.get_locus (),
367 "failed to resolve return type");
371 ret_type
= resolved
->clone ();
373 function
.get_return_type ()->get_mappings ().get_hirid ());
376 std::vector
<std::pair
<HIR::Pattern
*, TyTy::BaseType
*> > params
;
377 if (function
.is_method ())
379 // these are implicit mappings and not used
380 auto crate_num
= mappings
->get_current_crate ();
381 Analysis::NodeMapping
mapping (crate_num
, mappings
->get_next_node_id (),
382 mappings
->get_next_hir_id (crate_num
),
383 UNKNOWN_LOCAL_DEFID
);
385 // add the synthetic self param at the front, this is a placeholder for
386 // compilation to know parameter names. The types are ignored but we
387 // reuse the HIR identifier pattern which requires it
388 HIR::SelfParam
&self_param
= function
.get_self_param ();
389 // FIXME: which location should be used for Rust::Identifier for `self`?
390 HIR::IdentifierPattern
*self_pattern
= new HIR::IdentifierPattern (
391 mapping
, {"self"}, self_param
.get_locus (), self_param
.is_ref (),
392 self_param
.get_mut (), std::unique_ptr
<HIR::Pattern
> (nullptr));
394 // might have a specified type
395 TyTy::BaseType
*self_type
= nullptr;
396 if (self_param
.has_type ())
398 std::unique_ptr
<HIR::Type
> &specified_type
= self_param
.get_type ();
399 self_type
= TypeCheckType::Resolve (specified_type
.get ());
403 switch (self_param
.get_self_kind ())
405 case HIR::SelfParam::IMM
:
406 case HIR::SelfParam::MUT
:
407 self_type
= self
->clone ();
410 case HIR::SelfParam::IMM_REF
: {
411 auto region
= context
->lookup_and_resolve_lifetime (
412 self_param
.get_lifetime ());
413 if (!region
.has_value ())
415 rust_inform (self_param
.get_locus (),
416 "failed to resolve lifetime");
417 region
= TyTy::Region::make_anonymous (); // FIXME
419 self_type
= new TyTy::ReferenceType (
420 self_param
.get_mappings ().get_hirid (),
421 TyTy::TyVar (self
->get_ref ()), Mutability::Imm
,
426 case HIR::SelfParam::MUT_REF
: {
427 auto region
= context
->lookup_and_resolve_lifetime (
428 self_param
.get_lifetime ());
429 if (!region
.has_value ())
431 rust_error_at (self_param
.get_locus (),
432 "failed to resolve lifetime");
435 self_type
= new TyTy::ReferenceType (
436 self_param
.get_mappings ().get_hirid (),
437 TyTy::TyVar (self
->get_ref ()), Mutability::Mut
,
448 context
->insert_type (self_param
.get_mappings (), self_type
);
450 std::pair
<HIR::Pattern
*, TyTy::BaseType
*> (self_pattern
, self_type
));
453 for (auto ¶m
: function
.get_function_params ())
455 // get the name as well required for later on
456 auto param_tyty
= TypeCheckType::Resolve (param
.get_type ().get ());
457 params
.push_back (std::pair
<HIR::Pattern
*, TyTy::BaseType
*> (
458 param
.get_param_name ().get (), param_tyty
));
460 context
->insert_type (param
.get_mappings (), param_tyty
);
461 TypeCheckPattern::Resolve (param
.get_param_name ().get (), param_tyty
);
464 const CanonicalPath
*canonical_path
= nullptr;
466 = mappings
->lookup_canonical_path (function
.get_mappings ().get_nodeid (),
470 RustIdent ident
{*canonical_path
, function
.get_locus ()};
471 auto fnType
= new TyTy::FnType (
472 function
.get_mappings ().get_hirid (),
473 function
.get_mappings ().get_defid (),
474 function
.get_function_name ().as_string (), ident
,
475 function
.is_method () ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
476 : TyTy::FnType::FNTYPE_DEFAULT_FLAGS
,
477 ABI::RUST
, std::move (params
), ret_type
, std::move (substitutions
),
478 TyTy::SubstitutionArgumentMappings::empty (
479 context
->get_lifetime_resolver ().get_num_bound_regions ()),
482 context
->insert_type (function
.get_mappings (), fnType
);
485 // need to get the return type from this
486 TyTy::FnType
*resolve_fn_type
= fnType
;
487 auto expected_ret_tyty
= resolve_fn_type
->get_return_type ();
488 context
->push_return_type (TypeCheckContextItem (parent
, &function
),
492 = TypeCheckExpr::Resolve (function
.get_definition ().get ());
494 location_t fn_return_locus
= function
.has_function_return_type ()
495 ? function
.get_return_type ()->get_locus ()
496 : function
.get_locus ();
498 coercion_site (function
.get_definition ()->get_mappings ().get_hirid (),
499 TyTy::TyWithLocation (expected_ret_tyty
, fn_return_locus
),
500 TyTy::TyWithLocation (block_expr_ty
),
501 function
.get_definition ()->get_locus ());
503 context
->pop_return_type ();
507 TypeCheckImplItem::visit (HIR::ConstantItem
&constant
)
509 TyTy::BaseType
*type
= TypeCheckType::Resolve (constant
.get_type ().get ());
510 TyTy::BaseType
*expr_type
511 = TypeCheckExpr::Resolve (constant
.get_expr ().get ());
513 TyTy::BaseType
*unified
= unify_site (
514 constant
.get_mappings ().get_hirid (),
515 TyTy::TyWithLocation (type
, constant
.get_type ()->get_locus ()),
516 TyTy::TyWithLocation (expr_type
, constant
.get_expr ()->get_locus ()),
517 constant
.get_locus ());
518 context
->insert_type (constant
.get_mappings (), unified
);
523 TypeCheckImplItem::visit (HIR::TypeAlias
&alias
)
525 auto binder_pin
= context
->push_lifetime_binder ();
527 if (alias
.has_generics ())
528 resolve_generic_params (alias
.get_generic_params (), substitutions
);
530 TyTy::BaseType
*actual_type
531 = TypeCheckType::Resolve (alias
.get_type_aliased ().get ());
533 context
->insert_type (alias
.get_mappings (), actual_type
);
534 result
= actual_type
;
535 TyTy::RegionConstraints region_constraints
;
536 for (auto &where_clause_item
: alias
.get_where_clause ().get_items ())
538 ResolveWhereClauseItem::Resolve (*where_clause_item
.get (),
543 TypeCheckImplItemWithTrait::TypeCheckImplItemWithTrait (
544 HIR::ImplBlock
*parent
, TyTy::BaseType
*self
,
545 TyTy::TypeBoundPredicate
&trait_reference
,
546 std::vector
<TyTy::SubstitutionParamMapping
> substitutions
)
547 : TypeCheckBase (), trait_reference (trait_reference
),
548 resolved_trait_item (TyTy::TypeBoundPredicateItem::error ()),
549 parent (parent
), self (self
), substitutions (substitutions
)
551 rust_assert (is_trait_impl_block ());
554 TyTy::TypeBoundPredicateItem
555 TypeCheckImplItemWithTrait::Resolve (
556 HIR::ImplBlock
*parent
, HIR::ImplItem
*item
, TyTy::BaseType
*self
,
557 TyTy::TypeBoundPredicate
&trait_reference
,
558 std::vector
<TyTy::SubstitutionParamMapping
> substitutions
)
560 TypeCheckImplItemWithTrait
resolver (parent
, self
, trait_reference
,
562 item
->accept_vis (resolver
);
563 return resolver
.resolved_trait_item
;
567 TypeCheckImplItemWithTrait::visit (HIR::ConstantItem
&constant
)
569 // normal resolution of the item
570 TyTy::BaseType
*lookup
571 = TypeCheckImplItem::Resolve (parent
, &constant
, self
, substitutions
);
573 // map the impl item to the associated trait item
574 const auto tref
= trait_reference
.get ();
575 const TraitItemReference
*raw_trait_item
= nullptr;
577 = tref
->lookup_trait_item_by_type (constant
.get_identifier ().as_string (),
578 TraitItemReference::TraitItemType::CONST
,
581 // unknown trait item - https://doc.rust-lang.org/error_codes/E0323.html
582 if (!found
|| raw_trait_item
->is_error ())
584 rich_location
r (line_table
, constant
.get_locus ());
585 r
.add_range (trait_reference
.get_locus ());
586 rust_error_at (r
, ErrorCode::E0323
,
587 "item %qs is an associated const, which does not match "
589 constant
.get_identifier ().as_string ().c_str (),
590 trait_reference
.get_name ().c_str ());
594 // get the item from the predicate
595 resolved_trait_item
= trait_reference
.lookup_associated_item (raw_trait_item
);
596 rust_assert (!resolved_trait_item
.is_error ());
598 // merge the attributes
599 const HIR::TraitItem
*hir_trait_item
600 = resolved_trait_item
.get_raw_item ()->get_hir_trait_item ();
601 merge_attributes (constant
.get_outer_attrs (), *hir_trait_item
);
603 // check the types are compatible
604 auto trait_item_type
= resolved_trait_item
.get_tyty_for_receiver (self
);
605 if (!types_compatable (TyTy::TyWithLocation (trait_item_type
),
606 TyTy::TyWithLocation (lookup
), constant
.get_locus (),
607 true /*emit_errors*/))
609 rich_location
r (line_table
, constant
.get_locus ());
610 r
.add_range (resolved_trait_item
.get_locus ());
613 r
, "constant %<%s%> has an incompatible type for trait %<%s%>",
614 constant
.get_identifier ().as_string ().c_str (),
615 trait_reference
.get_name ().c_str ());
620 TypeCheckImplItemWithTrait::visit (HIR::TypeAlias
&type
)
622 // normal resolution of the item
623 TyTy::BaseType
*lookup
624 = TypeCheckImplItem::Resolve (parent
, &type
, self
, substitutions
);
626 // map the impl item to the associated trait item
627 const auto tref
= trait_reference
.get ();
628 const TraitItemReference
*raw_trait_item
= nullptr;
630 = tref
->lookup_trait_item_by_type (type
.get_new_type_name ().as_string (),
631 TraitItemReference::TraitItemType::TYPE
,
634 // unknown trait item
635 if (!found
|| raw_trait_item
->is_error ())
637 rich_location
r (line_table
, type
.get_locus ());
638 r
.add_range (trait_reference
.get_locus ());
639 rust_error_at (r
, "type alias %<%s%> is not a member of trait %<%s%>",
640 type
.get_new_type_name ().as_string ().c_str (),
641 trait_reference
.get_name ().c_str ());
645 // get the item from the predicate
646 resolved_trait_item
= trait_reference
.lookup_associated_item (raw_trait_item
);
647 rust_assert (!resolved_trait_item
.is_error ());
649 // merge the attributes
650 const HIR::TraitItem
*hir_trait_item
651 = resolved_trait_item
.get_raw_item ()->get_hir_trait_item ();
652 merge_attributes (type
.get_outer_attrs (), *hir_trait_item
);
654 // check the types are compatible
655 auto trait_item_type
= resolved_trait_item
.get_tyty_for_receiver (self
);
656 if (!types_compatable (TyTy::TyWithLocation (trait_item_type
),
657 TyTy::TyWithLocation (lookup
), type
.get_locus (),
658 true /*emit_errors*/))
660 rich_location
r (line_table
, type
.get_locus ());
661 r
.add_range (resolved_trait_item
.get_locus ());
664 r
, "type alias %<%s%> has an incompatible type for trait %<%s%>",
665 type
.get_new_type_name ().as_string ().c_str (),
666 trait_reference
.get_name ().c_str ());
669 // its actually a projection, since we need a way to actually bind the
670 // generic substitutions to the type itself
671 TyTy::ProjectionType
*projection
672 = new TyTy::ProjectionType (type
.get_mappings ().get_hirid (), lookup
, tref
,
673 raw_trait_item
->get_mappings ().get_defid (),
676 context
->insert_type (type
.get_mappings (), projection
);
677 raw_trait_item
->associated_type_set (projection
);
681 TypeCheckImplItemWithTrait::visit (HIR::Function
&function
)
683 // normal resolution of the item
684 TyTy::BaseType
*lookup
685 = TypeCheckImplItem::Resolve (parent
, &function
, self
, substitutions
);
687 // map the impl item to the associated trait item
688 const auto tref
= trait_reference
.get ();
689 const TraitItemReference
*raw_trait_item
= nullptr;
690 bool found
= tref
->lookup_trait_item_by_type (
691 function
.get_function_name ().as_string (),
692 TraitItemReference::TraitItemType::FN
, &raw_trait_item
);
694 // unknown trait item
695 if (!found
|| raw_trait_item
->is_error ())
697 rich_location
r (line_table
, function
.get_locus ());
698 r
.add_range (trait_reference
.get_locus ());
699 rust_error_at (r
, "method %<%s%> is not a member of trait %<%s%>",
700 function
.get_function_name ().as_string ().c_str (),
701 trait_reference
.get_name ().c_str ());
705 // get the item from the predicate
706 resolved_trait_item
= trait_reference
.lookup_associated_item (raw_trait_item
);
707 rust_assert (!resolved_trait_item
.is_error ());
709 // merge the attributes
710 const HIR::TraitItem
*hir_trait_item
711 = resolved_trait_item
.get_raw_item ()->get_hir_trait_item ();
712 merge_attributes (function
.get_outer_attrs (), *hir_trait_item
);
714 // check the types are compatible
715 auto trait_item_type
= resolved_trait_item
.get_tyty_for_receiver (self
);
716 if (!types_compatable (TyTy::TyWithLocation (trait_item_type
),
717 TyTy::TyWithLocation (lookup
), function
.get_locus (),
718 true /*emit_errors*/))
720 rich_location
r (line_table
, function
.get_locus ());
721 r
.add_range (resolved_trait_item
.get_locus ());
723 rust_error_at (r
, ErrorCode::E0053
,
724 "method %<%s%> has an incompatible type for trait %<%s%>",
725 function
.get_function_name ().as_string ().c_str (),
726 trait_reference
.get_name ().c_str ());
731 TypeCheckImplItemWithTrait::merge_attributes (AST::AttrVec
&impl_item_attrs
,
732 const HIR::TraitItem
&trait_item
)
734 for (const auto &attr
: trait_item
.get_outer_attrs ())
736 impl_item_attrs
.push_back (attr
);
741 TypeCheckImplItemWithTrait::is_trait_impl_block () const
743 return !trait_reference
.is_error ();
746 } // namespace Resolver