code: func (s *Scope) EvalExpr(expr hcl.Expression, wantType cty.Type) (cty.Value, tfdiags.Diagnostics) {
  	refs, diags := ReferencesInExpr(expr)
  
  	ctx, ctxDiags := s.EvalContext(refs)
  	diags = diags.Append(ctxDiags)
  	if diags.HasErrors() {
  		// We'll stop early if we found problems in the references, because
  		// it's likely evaluation will produce redundant copies of the same errors.
  		return cty.UnknownVal(wantType), diags
  	}
  
  	val, evalDiags := expr.Value(ctx)
  	diags = diags.Append(evalDiags)
  
  	if wantType != cty.DynamicPseudoType {
  		var convErr error
  		val, convErr = convert.Convert(val, wantType)
  		if convErr != nil {
  			val = cty.UnknownVal(wantType)
  			diags = diags.Append(&hcl.Diagnostic{
  				Severity: hcl.DiagError,
  				Summary:  "Incorrect value type",
  				Detail:   fmt.Sprintf("Invalid expression value: %s.", tfdiags.FormatError(convErr)),
  				Subject:  expr.Range().Ptr(),
  			})
  		}
  	}
  
  	return val, diags
  }
docs: // EvalExpr evaluates a single expression in the receiving context and returns
  // the resulting value. The value will be converted to the given type before
  // it is returned if possible, or else an error diagnostic will be produced
  // describing the conversion error.
  //
  // Pass an expected type of cty.DynamicPseudoType to skip automatic conversion
  // and just obtain the returned value directly.
  //
  // If the returned diagnostics contains errors then the result may be
  // incomplete, but will always be of the requested type.