code: func (c *Config) RequiredProviders() ProviderVersionConstraints {
  	ret := make(ProviderVersionConstraints, len(c.ProviderConfigs))
  
  	configs := c.ProviderConfigsByFullName()
  
  	// In order to find the *implied* dependencies (those without explicit
  	// "provider" blocks) we need to walk over all of the resources and
  	// cross-reference with the provider configs.
  	for _, rc := range c.Resources {
  		providerName := rc.ProviderFullName()
  		var providerType string
  
  		// Default to (effectively) no constraint whatsoever, but we might
  		// override if there's an explicit constraint in config.
  		constraint := ">=0.0.0"
  
  		config, ok := configs[providerName]
  		if ok {
  			if config.Version != "" {
  				constraint = config.Version
  			}
  			providerType = config.Name
  		} else {
  			providerType = providerName
  		}
  
  		ret[providerName] = ProviderVersionConstraint{
  			ProviderType: providerType,
  			Constraint:   constraint,
  		}
  	}
  
  	return ret
  }
docs: // RequiredProviders returns the ProviderVersionConstraints for this
  // module.
  //
  // This includes both providers that are explicitly requested by provider
  // blocks and those that are used implicitly by instantiating one of their
  // resource types. In the latter case, the returned semver Range will
  // accept any version of the provider.