From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id 588933AA9C2D; Wed, 8 Jun 2022 12:05:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 588933AA9C2D Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Thomas Schwinge To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] Remove AddressTakenContext X-Act-Checkin: gcc X-Git-Author: Philip Herron X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: f6ba472caf42db1f5f2f98b73afccf448b36c322 X-Git-Newrev: 859732e4d167dfe83b29cebc757f21ba2c342f33 Message-Id: <20220608120507.588933AA9C2D@sourceware.org> Date: Wed, 8 Jun 2022 12:05:07 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Jun 2022 12:05:07 -0000 https://gcc.gnu.org/g:859732e4d167dfe83b29cebc757f21ba2c342f33 commit 859732e4d167dfe83b29cebc757f21ba2c342f33 Author: Philip Herron Date: Thu Feb 10 15:40:23 2022 +0000 Remove AddressTakenContext We can reuse more C front-end code c_mark_addressable can be used instead of trying to track TREE_ADDRESSABLE as part of type-checking. This also pulls the GCC::Backend::address_expression to be part of the HIRCompileBase class during code-generation. Diff: --- gcc/rust/Make-lang.in | 1 - gcc/rust/backend/rust-compile-base.cc | 81 +++++++++++++ gcc/rust/backend/rust-compile-base.h | 4 + gcc/rust/backend/rust-compile-expr.cc | 17 ++- gcc/rust/backend/rust-compile-expr.h | 8 +- gcc/rust/backend/rust-compile-fnparam.h | 19 +-- gcc/rust/backend/rust-compile-var-decl.h | 17 ++- gcc/rust/backend/rust-compile.cc | 3 +- gcc/rust/rust-backend.h | 3 - gcc/rust/rust-gcc.cc | 13 --- gcc/rust/typecheck/rust-hir-address-taken.cc | 65 ----------- gcc/rust/typecheck/rust-hir-address-taken.h | 159 -------------------------- gcc/rust/typecheck/rust-hir-type-check-expr.h | 12 -- 13 files changed, 109 insertions(+), 293 deletions(-) diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index 2d745954c8a..660ed235a74 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -88,7 +88,6 @@ GRS_OBJS = \ rust/rust-hir-trait-resolve.o \ rust/rust-hir-type-check-type.o \ rust/rust-hir-type-check-struct.o \ - rust/rust-hir-address-taken.o \ rust/rust-hir-type-check-pattern.o \ rust/rust-autoderef.o \ rust/rust-substitution-mapper.o \ diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index 82a38e722a6..81598c4dc5b 100644 --- a/gcc/rust/backend/rust-compile-base.cc +++ b/gcc/rust/backend/rust-compile-base.cc @@ -17,6 +17,7 @@ // . #include "rust-compile-base.h" +#include "fold-const.h" #include "stringpool.h" namespace Rust { @@ -88,5 +89,85 @@ HIRCompileBase::setup_abi_options (tree fndecl, ABI abi) } } +// ported from gcc/c/c-typecheck.c +// +// Mark EXP saying that we need to be able to take the +// address of it; it should not be allocated in a register. +// Returns true if successful. ARRAY_REF_P is true if this +// is for ARRAY_REF construction - in that case we don't want +// to look through VIEW_CONVERT_EXPR from VECTOR_TYPE to ARRAY_TYPE, +// it is fine to use ARRAY_REFs for vector subscripts on vector +// register variables. +bool +HIRCompileBase::mark_addressable (tree exp, Location locus) +{ + tree x = exp; + + while (1) + switch (TREE_CODE (x)) + { + case VIEW_CONVERT_EXPR: + if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE + && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0)))) + return true; + x = TREE_OPERAND (x, 0); + break; + + case COMPONENT_REF: + // TODO + // if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1))) + // { + // error ("cannot take address of bit-field %qD", TREE_OPERAND (x, + // 1)); return false; + // } + + /* FALLTHRU */ + case ADDR_EXPR: + case ARRAY_REF: + case REALPART_EXPR: + case IMAGPART_EXPR: + x = TREE_OPERAND (x, 0); + break; + + case COMPOUND_LITERAL_EXPR: + TREE_ADDRESSABLE (x) = 1; + TREE_ADDRESSABLE (COMPOUND_LITERAL_EXPR_DECL (x)) = 1; + return true; + + case CONSTRUCTOR: + TREE_ADDRESSABLE (x) = 1; + return true; + + case VAR_DECL: + case CONST_DECL: + case PARM_DECL: + case RESULT_DECL: + // (we don't have a concept of a "register" declaration) + // fallthrough */ + + /* FALLTHRU */ + case FUNCTION_DECL: + TREE_ADDRESSABLE (x) = 1; + + /* FALLTHRU */ + default: + return true; + } + + return false; +} + +tree +HIRCompileBase::address_expression (tree expr, Location location) +{ + if (expr == error_mark_node) + return error_mark_node; + + if (!mark_addressable (expr, location)) + return error_mark_node; + + return build_fold_addr_expr_loc (location.gcc_location (), expr); +} + } // namespace Compile } // namespace Rust diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h index f318e81273c..ec7535648aa 100644 --- a/gcc/rust/backend/rust-compile-base.h +++ b/gcc/rust/backend/rust-compile-base.h @@ -77,6 +77,10 @@ protected: const HIR::FunctionQualifiers &qualifiers, const AST::AttrVec &attrs); static void setup_abi_options (tree fndecl, ABI abi); + + static tree address_expression (tree, Location); + + static bool mark_addressable (tree, Location); }; } // namespace Compile diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index d49a6dc4cd0..f65e1fd54c8 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -123,6 +123,13 @@ CompileExpr::visit (HIR::NegationExpr &expr) = ctx->get_backend ()->negation_expression (op, negated_expr, location); } +void +CompileExpr::visit (HIR::BorrowExpr &expr) +{ + tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx); + translated = address_expression (main_expr, expr.get_locus ()); +} + void CompileExpr::visit (HIR::DereferenceExpr &expr) { @@ -973,7 +980,7 @@ CompileExpr::compile_string_literal (const HIR::LiteralExpr &expr, auto base = ctx->get_backend ()->string_constant_expression ( literal_value.as_string ()); - return ctx->get_backend ()->address_expression (base, expr.get_locus ()); + return address_expression (base, expr.get_locus ()); } tree @@ -1006,8 +1013,7 @@ CompileExpr::compile_byte_string_literal (const HIR::LiteralExpr &expr, vals, expr.get_locus ()); - return ctx->get_backend ()->address_expression (constructed, - expr.get_locus ()); + return address_expression (constructed, expr.get_locus ()); } tree @@ -1190,7 +1196,7 @@ HIRCompileBase::resolve_adjustements ( case Resolver::Adjustment::AdjustmentType::IMM_REF: case Resolver::Adjustment::AdjustmentType::MUT_REF: - e = ctx->get_backend ()->address_expression (e, locus); + e = address_expression (e, locus); break; case Resolver::Adjustment::AdjustmentType::DEREF_REF: @@ -1235,8 +1241,7 @@ HIRCompileBase::resolve_deref_adjustment (Resolver::Adjustment &adjustment, != Resolver::Adjustment::AdjustmentType::ERROR; if (needs_borrow) { - adjusted_argument - = ctx->get_backend ()->address_expression (expression, locus); + adjusted_argument = address_expression (expression, locus); } // make the call diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 43eff722045..592d2806b21 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -797,13 +797,7 @@ public: ctx->add_statement (goto_label); } - void visit (HIR::BorrowExpr &expr) override - { - tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx); - - translated - = ctx->get_backend ()->address_expression (main_expr, expr.get_locus ()); - } + void visit (HIR::BorrowExpr &expr) override; void visit (HIR::DereferenceExpr &expr) override; diff --git a/gcc/rust/backend/rust-compile-fnparam.h b/gcc/rust/backend/rust-compile-fnparam.h index d8b63b6d62e..137bcad79aa 100644 --- a/gcc/rust/backend/rust-compile-fnparam.h +++ b/gcc/rust/backend/rust-compile-fnparam.h @@ -20,7 +20,6 @@ #define RUST_COMPILE_FNPARAM #include "rust-compile-base.h" -#include "rust-hir-address-taken.h" namespace Rust { namespace Compile { @@ -34,7 +33,7 @@ public: HIR::FunctionParam *param, tree decl_type, Location locus) { - CompileFnParam compiler (ctx, fndecl, decl_type, locus, *param); + CompileFnParam compiler (ctx, fndecl, decl_type, locus); param->get_param_name ()->accept_vis (compiler); return compiler.compiled_param; } @@ -45,9 +44,6 @@ public: decl_type = ctx->get_backend ()->immutable_type (decl_type); bool address_taken = false; - address_taken_context->lookup_addess_taken ( - param.get_mappings ().get_hirid (), &address_taken); - compiled_param = ctx->get_backend ()->parameter_variable ( fndecl, pattern.get_identifier (), decl_type, address_taken, locus); } @@ -63,20 +59,15 @@ public: } private: - CompileFnParam (Context *ctx, tree fndecl, tree decl_type, Location locus, - const HIR::FunctionParam ¶m) + CompileFnParam (Context *ctx, tree fndecl, tree decl_type, Location locus) : HIRCompileBase (ctx), fndecl (fndecl), decl_type (decl_type), - locus (locus), param (param), - compiled_param (ctx->get_backend ()->error_variable ()), - address_taken_context (Resolver::AddressTakenContext::get ()) + locus (locus), compiled_param (ctx->get_backend ()->error_variable ()) {} tree fndecl; tree decl_type; Location locus; - const HIR::FunctionParam ¶m; Bvariable *compiled_param; - const Resolver::AddressTakenContext *address_taken_context; }; class CompileSelfParam : public HIRCompileBase @@ -91,11 +82,7 @@ public: if (is_immutable) decl_type = ctx->get_backend ()->immutable_type (decl_type); - const auto &address_taken_context = Resolver::AddressTakenContext::get (); bool address_taken = false; - address_taken_context->lookup_addess_taken ( - self.get_mappings ().get_hirid (), &address_taken); - return ctx->get_backend ()->parameter_variable (fndecl, "self", decl_type, address_taken, locus); } diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h index 48becfade75..1da6cd4bca6 100644 --- a/gcc/rust/backend/rust-compile-var-decl.h +++ b/gcc/rust/backend/rust-compile-var-decl.h @@ -20,7 +20,6 @@ #define RUST_COMPILE_VAR_DECL #include "rust-compile-base.h" -#include "rust-hir-address-taken.h" namespace Rust { namespace Compile { @@ -47,9 +46,6 @@ public: &resolved_type); rust_assert (ok); - address_taken_context->lookup_addess_taken ( - stmt.get_mappings ().get_hirid (), &address_taken); - translated_type = TyTyResolveCompile::compile (ctx, resolved_type); stmt.get_pattern ()->accept_vis (*this); } @@ -59,6 +55,9 @@ public: if (!pattern.is_mut ()) translated_type = ctx->get_backend ()->immutable_type (translated_type); + // this gets updated when the compilation _actually_ wants to take an + // address + bool address_taken = false; compiled_variable = ctx->get_backend ()->local_variable (fndecl, pattern.get_identifier (), translated_type, NULL /*decl_var*/, @@ -68,6 +67,10 @@ public: void visit (HIR::WildcardPattern &pattern) override { translated_type = ctx->get_backend ()->immutable_type (translated_type); + + // this gets updated when the compilation _actually_ wants to take an + // address + bool address_taken = false; compiled_variable = ctx->get_backend ()->local_variable (fndecl, "_", translated_type, NULL /*decl_var*/, address_taken, @@ -78,17 +81,13 @@ private: CompileVarDecl (Context *ctx, tree fndecl) : HIRCompileBase (ctx), fndecl (fndecl), translated_type (ctx->get_backend ()->error_type ()), - compiled_variable (ctx->get_backend ()->error_variable ()), - address_taken (false), - address_taken_context (Resolver::AddressTakenContext::get ()) + compiled_variable (ctx->get_backend ()->error_variable ()) {} tree fndecl; tree translated_type; Location locus; Bvariable *compiled_variable; - bool address_taken; - const Resolver::AddressTakenContext *address_taken_context; }; } // namespace Compile diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index b0447af7505..2299ddbb93c 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -387,8 +387,7 @@ HIRCompileBase::coerce_to_dyn_object (tree compiled_ref, rust_assert (ok); resulting_dyn_object_ref - = ctx->get_backend ()->address_expression (resulting_dyn_object_ref, - locus); + = address_expression (resulting_dyn_object_ref, locus); } return resulting_dyn_object_ref; } diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h index 2a7691ca8f7..7d288923d7f 100644 --- a/gcc/rust/rust-backend.h +++ b/gcc/rust/rust-backend.h @@ -255,9 +255,6 @@ public: // get the address of the code for a function. virtual tree function_code_expression (tree, Location) = 0; - // Create an expression that takes the address of an expression. - virtual tree address_expression (tree, Location) = 0; - // Return an expression for the field at INDEX in BSTRUCT. virtual tree struct_field_expression (tree bstruct, size_t index, Location) = 0; diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc index 62c9d80b213..d83dd4d2e1e 100644 --- a/gcc/rust/rust-gcc.cc +++ b/gcc/rust/rust-gcc.cc @@ -231,8 +231,6 @@ public: tree function_code_expression (tree, Location); - tree address_expression (tree, Location); - tree struct_field_expression (tree, size_t, Location); tree compound_expression (tree, tree, Location); @@ -1338,17 +1336,6 @@ Gcc_backend::function_code_expression (tree func, Location location) return ret; } -// Get the address of an expression. - -tree -Gcc_backend::address_expression (tree expr, Location location) -{ - if (expr == error_mark_node) - return this->error_expression (); - - return build_fold_addr_expr_loc (location.gcc_location (), expr); -} - // Return an expression for the field at INDEX in BSTRUCT. tree diff --git a/gcc/rust/typecheck/rust-hir-address-taken.cc b/gcc/rust/typecheck/rust-hir-address-taken.cc deleted file mode 100644 index 8fcbb377f64..00000000000 --- a/gcc/rust/typecheck/rust-hir-address-taken.cc +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2020-2022 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#include "rust-hir-address-taken.h" -#include "rust-hir-full.h" - -namespace Rust { -namespace Resolver { - -AddressTakenContext * -AddressTakenContext::get () -{ - static AddressTakenContext *instance; - if (instance == nullptr) - instance = new AddressTakenContext (); - - return instance; -} - -AddressTakenContext::~AddressTakenContext () {} - -bool -AddressTakenContext::lookup_addess_taken (HirId id, bool *address_taken) const -{ - const auto &it = ctx.find (id); - if (it == ctx.end ()) - return false; - - *address_taken = it->second; - return true; -} - -void -AddressTakenContext::insert_address_taken (HirId id, bool address_taken) -{ - const auto &it = ctx.find (id); - if (it != ctx.end ()) - { - // assert that we never change a true result to a negative - if (it->second == true) - { - rust_assert (address_taken != false); - } - } - - ctx[id] = address_taken; -} - -} // namespace Resolver -} // namespace Rust diff --git a/gcc/rust/typecheck/rust-hir-address-taken.h b/gcc/rust/typecheck/rust-hir-address-taken.h deleted file mode 100644 index 32a1445ae4d..00000000000 --- a/gcc/rust/typecheck/rust-hir-address-taken.h +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (C) 2020-2022 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#ifndef RUST_HIR_ADDRESS_TAKEN -#define RUST_HIR_ADDRESS_TAKEN - -#include "rust-hir-type-check-base.h" - -namespace Rust { -namespace Resolver { - -class AddressTakenContext -{ -public: - static AddressTakenContext *get (); - - ~AddressTakenContext (); - - bool lookup_addess_taken (HirId id, bool *address_taken) const; - - void insert_address_taken (HirId id, bool address_taken); - -private: - std::map ctx; -}; - -class AddressTakenResolver : public TypeCheckBase -{ - using Rust::Resolver::TypeCheckBase::visit; - -public: - static void SetAddressTaken (HIR::Expr &expr) - { - AddressTakenResolver resolver; - expr.accept_vis (resolver); - } - - void visit (HIR::IdentifierExpr &expr) override - { - NodeId ast_node_id = expr.get_mappings ().get_nodeid (); - NodeId ref_node_id = UNKNOWN_NODEID; - if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id)) - { - // these ref_node_ids will resolve to a pattern declaration but we are - // interested in the definition that this refers to get the parent id - Definition def; - if (!resolver->lookup_definition (ref_node_id, &def)) - { - rust_error_at (expr.get_locus (), - "unknown reference for resolved name"); - return; - } - ref_node_id = def.parent; - } - - if (ref_node_id == UNKNOWN_NODEID) - return; - - // node back to HIR - HirId ref = UNKNOWN_HIRID; - bool reverse_lookup - = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (), - ref_node_id, &ref); - rust_assert (reverse_lookup); - context->insert_address_taken (ref, true); - } - - void visit (HIR::PathInExpression &expr) override - { - NodeId ast_node_id = expr.get_mappings ().get_nodeid (); - NodeId ref_node_id = UNKNOWN_NODEID; - if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id)) - { - // these ref_node_ids will resolve to a pattern declaration but we are - // interested in the definition that this refers to get the parent id - Definition def; - if (!resolver->lookup_definition (ref_node_id, &def)) - { - rust_error_at (expr.get_locus (), - "unknown reference for resolved name"); - return; - } - ref_node_id = def.parent; - } - - if (ref_node_id == UNKNOWN_NODEID) - return; - - // node back to HIR - HirId ref = UNKNOWN_HIRID; - bool reverse_lookup - = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (), - ref_node_id, &ref); - rust_assert (reverse_lookup); - context->insert_address_taken (ref, true); - } - - void visit (HIR::QualifiedPathInExpression &expr) override - { - NodeId ast_node_id = expr.get_mappings ().get_nodeid (); - NodeId ref_node_id = UNKNOWN_NODEID; - if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id)) - { - // these ref_node_ids will resolve to a pattern declaration but we are - // interested in the definition that this refers to get the parent id - Definition def; - if (!resolver->lookup_definition (ref_node_id, &def)) - { - rust_error_at (expr.get_locus (), - "unknown reference for resolved name"); - return; - } - ref_node_id = def.parent; - } - - if (ref_node_id == UNKNOWN_NODEID) - return; - - // node back to HIR - HirId ref = UNKNOWN_HIRID; - bool reverse_lookup - = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (), - ref_node_id, &ref); - rust_assert (reverse_lookup); - context->insert_address_taken (ref, true); - } - - void visit (HIR::DereferenceExpr &expr) override - { - expr.get_expr ()->accept_vis (*this); - } - -private: - AddressTakenResolver () - : TypeCheckBase (), context (AddressTakenContext::get ()) - {} - - AddressTakenContext *context; -}; - -} // namespace Resolver -} // namespace Rust - -#endif // RUST_HIR_ADDRESS_TAKEN diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 150eb1a52d6..2cb4461886e 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -30,7 +30,6 @@ #include "rust-hir-trait-resolve.h" #include "rust-hir-type-bounds.h" #include "rust-hir-dot-operator.h" -#include "rust-hir-address-taken.h" #include "rust-hir-type-check-pattern.h" namespace Rust { @@ -260,10 +259,6 @@ public: Adjuster adj (receiver_tyty); TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments); - // mark the required tree addressable - if (Adjuster::needs_address (candidate.adjustments)) - AddressTakenResolver::SetAddressTaken (*expr.get_receiver ().get ()); - // store the adjustments for code-generation to know what to do context->insert_autoderef_mappings (expr.get_mappings ().get_hirid (), std::move (candidate.adjustments)); @@ -1177,9 +1172,6 @@ public: infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (), TyTy::TyVar (resolved_base->get_ref ()), expr.get_mut ()); - - // mark the borrowed as address_taken - AddressTakenResolver::SetAddressTaken (*expr.get_expr ().get ()); } void visit (HIR::DereferenceExpr &expr) override @@ -1350,10 +1342,6 @@ protected: } } - // mark the required tree addressable - if (Adjuster::needs_address (candidate.adjustments)) - AddressTakenResolver::SetAddressTaken (*expr.get_expr ().get ()); - // store the adjustments for code-generation to know what to do context->insert_autoderef_mappings (expr.get_mappings ().get_hirid (), std::move (candidate.adjustments));