handle_require.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/base/kind_switch.h"
  5. #include "toolchain/check/context.h"
  6. #include "toolchain/check/convert.h"
  7. #include "toolchain/check/generic.h"
  8. #include "toolchain/check/handle.h"
  9. #include "toolchain/check/inst.h"
  10. #include "toolchain/check/modifiers.h"
  11. #include "toolchain/check/name_lookup.h"
  12. #include "toolchain/check/period_self.h"
  13. #include "toolchain/check/subst.h"
  14. #include "toolchain/check/type.h"
  15. #include "toolchain/check/type_completion.h"
  16. #include "toolchain/diagnostics/diagnostic.h"
  17. #include "toolchain/parse/node_ids.h"
  18. #include "toolchain/sem_ir/ids.h"
  19. #include "toolchain/sem_ir/named_constraint.h"
  20. #include "toolchain/sem_ir/specific_named_constraint.h"
  21. #include "toolchain/sem_ir/type_iterator.h"
  22. #include "toolchain/sem_ir/typed_insts.h"
  23. namespace Carbon::Check {
  24. auto HandleParseNode(Context& context, Parse::RequireIntroducerId node_id)
  25. -> bool {
  26. // Require decls are always generic, since everything in an `interface` or
  27. // `constraint` is generic over `Self`.
  28. StartGenericDecl(context);
  29. // Create an instruction block to hold the instructions created for the type
  30. // and constraint.
  31. context.inst_block_stack().Push();
  32. // Optional modifiers follow.
  33. context.decl_introducer_state_stack().Push<Lex::TokenKind::Require>();
  34. auto scope_id = context.scope_stack().PeekNameScopeId();
  35. auto scope_inst_id = context.name_scopes().Get(scope_id).inst_id();
  36. auto scope_inst = context.insts().Get(scope_inst_id);
  37. if (!scope_inst.Is<SemIR::InterfaceWithSelfDecl>() &&
  38. !scope_inst.Is<SemIR::NamedConstraintWithSelfDecl>()) {
  39. CARBON_DIAGNOSTIC(
  40. RequireInWrongScope, Error,
  41. "`require` can only be used in an `interface` or `constraint`");
  42. context.emitter().Emit(node_id, RequireInWrongScope);
  43. scope_inst_id = SemIR::ErrorInst::InstId;
  44. }
  45. context.node_stack().Push(node_id, scope_inst_id);
  46. return true;
  47. }
  48. auto HandleParseNode(Context& context, Parse::RequireDefaultSelfImplsId node_id)
  49. -> bool {
  50. auto scope_inst_id =
  51. context.node_stack().Peek<Parse::NodeKind::RequireIntroducer>();
  52. if (scope_inst_id == SemIR::ErrorInst::InstId) {
  53. context.node_stack().Push(node_id, SemIR::ErrorInst::TypeInstId);
  54. return true;
  55. }
  56. auto lookup_result =
  57. LookupUnqualifiedName(context, node_id, SemIR::NameId::SelfType,
  58. /*required=*/true);
  59. auto self_inst_id = lookup_result.scope_result.target_inst_id();
  60. auto self_type_id = context.insts().Get(self_inst_id).type_id();
  61. if (self_type_id == SemIR::ErrorInst::TypeId) {
  62. context.node_stack().Push(node_id, SemIR::ErrorInst::TypeInstId);
  63. return true;
  64. }
  65. CARBON_CHECK(context.types().Is<SemIR::FacetType>(self_type_id));
  66. // TODO: We could simplify with a call to ExprAsType, like below?
  67. auto self_facet_as_type = AddTypeInst<SemIR::FacetAccessType>(
  68. context, node_id,
  69. {.type_id = SemIR::TypeType::TypeId,
  70. .facet_value_inst_id = self_inst_id});
  71. context.node_stack().Push(node_id, self_facet_as_type);
  72. return true;
  73. }
  74. auto HandleParseNode(Context& context, Parse::RequireTypeImplsId node_id)
  75. -> bool {
  76. auto [self_node_id, self_inst_id] = context.node_stack().PopExprWithNodeId();
  77. auto self_type = ExprAsType(context, self_node_id, self_inst_id);
  78. const auto& introducer = context.decl_introducer_state_stack().innermost();
  79. if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extend)) {
  80. if (self_type.type_id != SemIR::ErrorInst::TypeId) {
  81. CARBON_DIAGNOSTIC(RequireImplsExtendWithExplicitSelf, Error,
  82. "`extend require impls` with explicit type");
  83. // TODO: If the explicit self-type matches a lookup of NameId::SelfType,
  84. // add a note to the diagnostic: "remove the explicit `Self` type here",
  85. // and continue without an ErrorInst. See ExtendImplSelfAsDefault.
  86. context.emitter().Emit(self_node_id, RequireImplsExtendWithExplicitSelf);
  87. }
  88. self_type.inst_id = SemIR::ErrorInst::TypeInstId;
  89. }
  90. context.node_stack().Push(node_id, self_type.inst_id);
  91. return true;
  92. }
  93. static auto TypeStructureReferencesSelf(
  94. Context& context, SemIR::LocId loc_id, SemIR::ConstantId const_id,
  95. const SemIR::IdentifiedFacetType& identified_facet_type) -> bool {
  96. auto find_self = [&](SemIR::TypeIterator& type_iter) -> bool {
  97. while (true) {
  98. auto step = type_iter.Next();
  99. if (step.Is<SemIR::TypeIterator::Step::Done>()) {
  100. break;
  101. }
  102. CARBON_KIND_SWITCH(step.any) {
  103. case CARBON_KIND(SemIR::TypeIterator::Step::Error _): {
  104. // Don't generate more diagnostics.
  105. return true;
  106. }
  107. case CARBON_KIND(SemIR::TypeIterator::Step::SymbolicType symbolic): {
  108. if (context.entity_names().Get(symbolic.entity_name_id).name_id ==
  109. SemIR::NameId::SelfType) {
  110. return true;
  111. }
  112. break;
  113. }
  114. default:
  115. break;
  116. }
  117. }
  118. return false;
  119. };
  120. {
  121. SemIR::TypeIterator type_iter(&context.sem_ir());
  122. type_iter.Add(context.constant_values().GetInstId(const_id));
  123. if (find_self(type_iter)) {
  124. return true;
  125. }
  126. }
  127. if (identified_facet_type.required_impls().empty()) {
  128. CARBON_DIAGNOSTIC(
  129. RequireImplsMissingSelfEmptyFacetType, Error,
  130. "no `Self` reference found in `require` declaration; `Self` must "
  131. "appear in the self-type or as a generic argument for each required "
  132. "interface, but no interfaces were found");
  133. context.emitter().Emit(loc_id, RequireImplsMissingSelfEmptyFacetType);
  134. return false;
  135. }
  136. bool interfaces_all_reference_self = true;
  137. for (auto [_, specific_interface] : identified_facet_type.required_impls()) {
  138. SemIR::TypeIterator type_iter(&context.sem_ir());
  139. type_iter.Add(specific_interface);
  140. if (!find_self(type_iter)) {
  141. // TODO: The IdentifiedFacetType loses the location (since it's
  142. // canonical), but it would be nice to somehow point this diagnostic at
  143. // the particular interface in the facet type that is missing `Self`.
  144. CARBON_DIAGNOSTIC(
  145. RequireImplsMissingSelf, Error,
  146. "no `Self` reference found in `require` declaration; `Self` must "
  147. "appear in the self-type or as a generic argument for each required "
  148. "interface, but found interface `{0}` without a `Self` argument",
  149. SemIR::SpecificInterface);
  150. context.emitter().Emit(loc_id, RequireImplsMissingSelf,
  151. specific_interface);
  152. interfaces_all_reference_self = false;
  153. }
  154. }
  155. return interfaces_all_reference_self;
  156. }
  157. struct ValidateRequireResult {
  158. const SemIR::IdentifiedFacetType* identified_facet_type;
  159. };
  160. // Returns nullopt if a diagnostic has been emitted and the `require` decl is
  161. // not valid.
  162. static auto ValidateRequire(Context& context, SemIR::LocId full_require_loc_id,
  163. SemIR::LocId constraint_loc_id,
  164. SemIR::InstId self_inst_id,
  165. SemIR::InstId constraint_inst_id,
  166. SemIR::InstId scope_inst_id)
  167. -> std::optional<ValidateRequireResult> {
  168. auto self_type_id = context.types().GetTypeIdForTypeInstId(self_inst_id);
  169. auto constraint_type_id =
  170. context.types().TryGetTypeIdForTypeInstId(constraint_inst_id);
  171. if (self_type_id == SemIR::ErrorInst::TypeId ||
  172. constraint_type_id == SemIR::ErrorInst::TypeId ||
  173. scope_inst_id == SemIR::ErrorInst::InstId) {
  174. // An error was already diagnosed, don't diagnose another. We can't build a
  175. // useful `require` with an error, it couldn't do anything.
  176. return std::nullopt;
  177. }
  178. auto constraint_facet_type =
  179. context.types().TryGetAsIfValid<SemIR::FacetType>(constraint_type_id);
  180. if (!constraint_facet_type) {
  181. CARBON_DIAGNOSTIC(
  182. RequireImplsMissingFacetType, Error,
  183. "`require` declaration constrained by a non-facet type; "
  184. "expected an `interface` or `constraint` name after `impls`");
  185. context.emitter().Emit(constraint_loc_id, RequireImplsMissingFacetType);
  186. // Can't continue without a constraint to use.
  187. return std::nullopt;
  188. }
  189. if (auto named_constraint =
  190. context.insts().TryGetAs<SemIR::NamedConstraintWithSelfDecl>(
  191. scope_inst_id)) {
  192. const auto& constraint_facet_type_info =
  193. context.facet_types().Get(constraint_facet_type->facet_type_id);
  194. // TODO: Handle other impls named constraints for the
  195. // RequireImplsReferenceCycle diagnostic.
  196. if (constraint_facet_type_info.other_requirements) {
  197. context.TODO(constraint_loc_id,
  198. "facet type has constraints that we don't handle yet");
  199. return std::nullopt;
  200. }
  201. auto named_constraints_from_type_impls = llvm::map_range(
  202. constraint_facet_type_info.type_impls_named_constraints,
  203. [](auto impls) { return impls.specific_named_constraint; });
  204. auto named_constraints = llvm::concat<const SemIR::SpecificNamedConstraint>(
  205. constraint_facet_type_info.extend_named_constraints,
  206. constraint_facet_type_info.self_impls_named_constraints,
  207. named_constraints_from_type_impls);
  208. for (auto c : named_constraints) {
  209. if (c.named_constraint_id == named_constraint->named_constraint_id) {
  210. const auto& named_constraint =
  211. context.named_constraints().Get(c.named_constraint_id);
  212. CARBON_DIAGNOSTIC(RequireImplsReferenceCycle, Error,
  213. "facet type in `require` declaration refers to the "
  214. "named constraint `{0}` from within its definition",
  215. SemIR::NameId);
  216. context.emitter().Emit(constraint_loc_id, RequireImplsReferenceCycle,
  217. named_constraint.name_id);
  218. return std::nullopt;
  219. }
  220. }
  221. }
  222. auto identified_facet_type_id = RequireIdentifiedFacetType(
  223. context, constraint_loc_id, self_type_id.AsConstantId(),
  224. *constraint_facet_type, [&](auto& builder) {
  225. CARBON_DIAGNOSTIC(
  226. RequireImplsUnidentifiedFacetType, Context,
  227. "facet type {0} cannot be identified in `require` declaration",
  228. SemIR::TypeId);
  229. builder.Context(constraint_loc_id, RequireImplsUnidentifiedFacetType,
  230. constraint_type_id);
  231. });
  232. if (!identified_facet_type_id.has_value()) {
  233. // The constraint can't be used. A diagnostic was emitted by
  234. // RequireIdentifiedFacetType().
  235. return std::nullopt;
  236. }
  237. const auto& identified =
  238. context.identified_facet_types().Get(identified_facet_type_id);
  239. if (!TypeStructureReferencesSelf(context, full_require_loc_id,
  240. self_type_id.AsConstantId(), identified)) {
  241. return std::nullopt;
  242. }
  243. return ValidateRequireResult{.identified_facet_type = &identified};
  244. }
  245. // Replace all `.Self` references with the self-type.
  246. static auto SubstPeriodSelfInConstraint(Context& context, SemIR::LocId loc_id,
  247. SemIR::TypeInstId self_type_inst_id,
  248. SemIR::TypeInstId constraint_inst_id)
  249. -> SemIR::TypeInstId {
  250. auto orig_facet_type = context.insts().GetAs<SemIR::FacetType>(
  251. context.constant_values().GetConstantInstId(constraint_inst_id));
  252. const auto& orig_info =
  253. context.facet_types().Get(orig_facet_type.facet_type_id);
  254. SubstPeriodSelfCallbacks callbacks(
  255. &context, loc_id, context.constant_values().Get(self_type_inst_id));
  256. auto replace_interface = [&](SemIR::SpecificInterface si) {
  257. return SubstPeriodSelf(context, callbacks, si);
  258. };
  259. auto replace_constraint = [&](SemIR::SpecificNamedConstraint sc) {
  260. return SubstPeriodSelf(context, callbacks, sc);
  261. };
  262. auto replace_type_impls_interface =
  263. [&](SemIR::FacetTypeInfo::TypeImplsInterface impls)
  264. -> SemIR::FacetTypeInfo::TypeImplsInterface {
  265. auto self = SubstPeriodSelf(context, callbacks,
  266. context.constant_values().Get(impls.self_type));
  267. auto interface =
  268. SubstPeriodSelf(context, callbacks, impls.specific_interface);
  269. return {context.constant_values().GetInstId(self), interface};
  270. };
  271. auto replace_type_impls_constraint =
  272. [&](SemIR::FacetTypeInfo::TypeImplsNamedConstraint impls)
  273. -> SemIR::FacetTypeInfo::TypeImplsNamedConstraint {
  274. auto self = SubstPeriodSelf(context, callbacks,
  275. context.constant_values().Get(impls.self_type));
  276. auto constraint =
  277. SubstPeriodSelf(context, callbacks, impls.specific_named_constraint);
  278. return {context.constant_values().GetInstId(self), constraint};
  279. };
  280. SemIR::FacetTypeInfo info;
  281. llvm::append_range(
  282. info.extend_constraints,
  283. llvm::map_range(orig_info.extend_constraints, replace_interface));
  284. llvm::append_range(
  285. info.extend_named_constraints,
  286. llvm::map_range(orig_info.extend_named_constraints, replace_constraint));
  287. llvm::append_range(
  288. info.self_impls_constraints,
  289. llvm::map_range(orig_info.self_impls_constraints, replace_interface));
  290. llvm::append_range(info.self_impls_named_constraints,
  291. llvm::map_range(orig_info.self_impls_named_constraints,
  292. replace_constraint));
  293. llvm::append_range(info.type_impls_interfaces,
  294. llvm::map_range(orig_info.type_impls_interfaces,
  295. replace_type_impls_interface));
  296. llvm::append_range(info.type_impls_named_constraints,
  297. llvm::map_range(orig_info.type_impls_named_constraints,
  298. replace_type_impls_constraint));
  299. // TODO: Replace .Self in rewrites too. We need to actually validate rewrite
  300. // constraints from named constraints in impl lookup (see
  301. // todo_fail_require_with_mismatching_rewrite_constraint.carbon).
  302. llvm::append_range(info.rewrite_constraints, orig_info.rewrite_constraints);
  303. info.Canonicalize();
  304. if (info == orig_info) {
  305. // Nothing was substituted, keep the original instruction.
  306. //
  307. // It is noteworthy that we keep the non-canonical instruction here, since
  308. // it may have a symbolic value (which is attached to a generic, and can be
  309. // updated by specifics). Returning the canonical constraint instruction
  310. // would lose the attachment to the generic which would be incorrect.
  311. return constraint_inst_id;
  312. }
  313. return AddTypeInst<SemIR::FacetType>(
  314. context, loc_id,
  315. {.type_id = SemIR::TypeType::TypeId,
  316. .facet_type_id = context.facet_types().Add(info)});
  317. }
  318. auto HandleParseNode(Context& context, Parse::RequireDeclId node_id) -> bool {
  319. auto [constraint_node_id, constraint_inst_id] =
  320. context.node_stack().PopExprWithNodeId();
  321. auto [self_node_id, self_inst_id] =
  322. context.node_stack().PopWithNodeId<Parse::NodeCategory::RequireImpls>();
  323. // Process modifiers.
  324. auto introducer =
  325. context.decl_introducer_state_stack().Pop<Lex::TokenKind::Require>();
  326. LimitModifiersOnDecl(context, introducer, KeywordModifierSet::Extend);
  327. bool extend = introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extend);
  328. auto scope_inst_id =
  329. context.node_stack().Pop<Parse::NodeKind::RequireIntroducer>();
  330. auto validated =
  331. ValidateRequire(context, node_id, constraint_node_id, self_inst_id,
  332. constraint_inst_id, scope_inst_id);
  333. if (!validated) {
  334. // In an `extend` decl, errors get propagated into the parent scope just as
  335. // names do.
  336. if (extend) {
  337. auto scope_id = context.scope_stack().PeekNameScopeId();
  338. context.name_scopes().Get(scope_id).set_has_error();
  339. }
  340. context.inst_block_stack().Pop();
  341. DiscardGenericDecl(context);
  342. return true;
  343. }
  344. auto [identified_facet_type] = *validated;
  345. if (identified_facet_type->required_impls().empty()) {
  346. // A `require T impls type` adds no actual constraints, so nothing to do.
  347. // This is not an error though.
  348. context.inst_block_stack().Pop();
  349. DiscardGenericDecl(context);
  350. return true;
  351. }
  352. // The identified facet type also replaced `.Self` references, but we want to
  353. // store the full facet type not just the identified one. So we have to
  354. // replace `.Self` references explicitly here in the canonical constraint. We
  355. // do this after `ValidateRequire()` which has ensured the constraint is in
  356. // fact a FacetType.
  357. auto constraint_type_inst_id = SubstPeriodSelfInConstraint(
  358. context, constraint_node_id, self_inst_id,
  359. context.types().GetAsTypeInstId(constraint_inst_id));
  360. // The replacement of `.Self` can create a new FacetType instruction which we
  361. // want to be part of the require decl's inst block, so we defer the Pop until
  362. // after the subst.
  363. auto decl_block_id = context.inst_block_stack().Pop();
  364. auto require_impls_decl =
  365. SemIR::RequireImplsDecl{// To be filled in after.
  366. .require_impls_id = SemIR::RequireImplsId::None,
  367. .decl_block_id = decl_block_id};
  368. auto decl_id = AddPlaceholderInst(context, node_id, require_impls_decl);
  369. // TODO: We don't need to store the `self_inst_id` anymore, since we've
  370. // encoded it into the constraints of the facet type which was converted to
  371. // the form `<Self> where .Self impls <Constraint>`.
  372. auto require_impls_id = context.require_impls().Add(
  373. {.self_id = self_inst_id,
  374. .facet_type_inst_id = constraint_type_inst_id,
  375. .extend_self = extend,
  376. .decl_id = decl_id,
  377. .parent_scope_id = context.scope_stack().PeekNameScopeId(),
  378. .generic_id = BuildGenericDecl(context, decl_id)});
  379. require_impls_decl.require_impls_id = require_impls_id;
  380. ReplaceInstBeforeConstantUse(context, decl_id, require_impls_decl);
  381. // We look for a complete type after BuildGenericDecl, so that the resulting
  382. // RequireCompleteType instruction is part of the enclosing interface or named
  383. // constraint generic definition. Then requiring enclosing entity to be
  384. // complete will resolve that definition (via ResolveSpecificDefinition()) and
  385. // also construct a specific for the `constraint_inst_id`, finding any
  386. // monomorphization errors that result.
  387. if (extend) {
  388. if (!RequireCompleteType(
  389. context,
  390. context.types().GetTypeIdForTypeInstId(constraint_type_inst_id),
  391. constraint_node_id, [&](auto& builder) {
  392. CARBON_DIAGNOSTIC(RequireImplsIncompleteFacetType, Context,
  393. "`extend require` of incomplete facet type {0}",
  394. InstIdAsType);
  395. builder.Context(constraint_node_id,
  396. RequireImplsIncompleteFacetType,
  397. constraint_type_inst_id);
  398. })) {
  399. return true;
  400. }
  401. // The extended scope instruction must be part of the enclosing scope (and
  402. // generic). A specific for the enclosing scope will be applied to it when
  403. // using the instruction later. To do so, we wrap the constraint facet type
  404. // it in a SpecificConstant, which preserves the require declaration's
  405. // specific along with the facet type.
  406. //
  407. // TODO: Remove the separate generic for each require decl, then we don't
  408. // need a SpecificConstant anymore, as the constraint_inst_id will already
  409. // be in the generic of the interface-with-self.
  410. auto self_specific_id = context.generics().GetSelfSpecific(
  411. context.require_impls().Get(require_impls_id).generic_id);
  412. auto constraint_id_in_self_specific = AddTypeInst<SemIR::SpecificConstant>(
  413. context, node_id,
  414. {.type_id = SemIR::TypeType::TypeId,
  415. .inst_id = constraint_inst_id,
  416. .specific_id = self_specific_id});
  417. auto enclosing_scope_id = context.scope_stack().PeekNameScopeId();
  418. auto& enclosing_scope = context.name_scopes().Get(enclosing_scope_id);
  419. enclosing_scope.AddExtendedScope(constraint_id_in_self_specific);
  420. }
  421. context.require_impls_stack().AppendToTop(require_impls_id);
  422. return true;
  423. }
  424. } // namespace Carbon::Check