code: func (s *Scope) EvalReference(ref *addrs.Reference, wantType cty.Type) (cty.Value, tfdiags.Diagnostics) {
  	var diags tfdiags.Diagnostics
  
  	// We cheat a bit here and just build an EvalContext for our requested
  	// reference with the "self" address overridden, and then pull the "self"
  	// result out of it to return.
  	ctx, ctxDiags := s.evalContext([]*addrs.Reference{ref}, ref.Subject)
  	diags = diags.Append(ctxDiags)
  	val := ctx.Variables["self"]
  	if val == cty.NilVal {
  		val = cty.DynamicVal
  	}
  
  	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:  ref.SourceRange.ToHCL().Ptr(),
  		})
  	}
  
  	return val, diags
  }
docs: // EvalReference evaluates the given reference in the receiving scope 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.