Skip to content

Conversation

gradha
Copy link
Contributor

@gradha gradha commented Jan 28, 2014

Made against devel branch. Adds more documentation. Replaces #793.

@gradha gradha mentioned this pull request Jan 28, 2014
Araq added a commit that referenced this pull request Apr 7, 2014
@Araq
Copy link
Member

Araq commented Apr 7, 2014

Merged it manually.

@Araq Araq closed this Apr 7, 2014
@gradha gradha deleted the pr_better_html_links_devel branch April 8, 2014 09:57
Araq added a commit that referenced this pull request Apr 9, 2014
Clyybber pushed a commit to Clyybber/Nim that referenced this pull request Sep 16, 2023
## Summary

Fix complex type-variable-dependent expressions not working reliably
for range and array-index types used in routine signatures.
Internally, expressions in both contexts are now first treated as
generic, and using `replaceTypesInBody` for expressions with
potentially unbound type variables is removed.

**Language changes:**
- syntax macros and templates (i.e., those where all parameters are 
  `untyped`) used in range- and index-type expression are expanded
  before all further analysis (and thus typed macros/template, static
  expressions, etc.)
- typed macros and templates used in range- and index-type expressions
  depending on type variables are potentially expanded multiple times

**Fixes:**
- type-variable-dependent range and array-index types in routine
  signatures can now be arbitrarily complex (refer to the added tests
  for an example of what is now possible)

## Details

**Overview:**
- all expressions used with range types and in array-index positions
  now use the generic pre-pass
- type-variable-dependent expressions in range type constructors are
  now always generic expressions (i.e., symbols are looked up, but
  not AST is not typed)
- `replaceTypesInBody` is renamed to `instantiateTypesInBody` and
  support for unresolved type variables is removed -- the new
  `replaceTypeVarsInBody` now has to be used for that case

Semantic analysis has very basic, scattered support for expressions
depending on unresolved type variables, allowing `semExprWithType` to
be used for typing expressions in range and array type constructors.
However, in more complex cases, this usually results in errors with
unclear descriptions. Until more complete support for typing expressions
depending on unresolved type variables is implemented, it is more
robust to treat them as fully generic.

### Analyzing the expressions

Both `semRangeAux` and `semArrayIndex` now always run the generic pre-
pass first (`semGenericStmt`, which also expands syntax macros), which
is required for detecting whether unresolved type variables are used.
When no unresolved type variables exist in the analyzed expression, it
is directly passed on to `semExprWithType`.

The procedure for querying whether a symbol is that of an unresolved
type variable (`isUnresolvedSym`), is moved to the `ast_query`
module.

Looking for unresolved type variables is combined with making sure that
all type variables are referenced in the AST via their symbols
(`fixupTypeVars`) -- something that is not always already the case. Some
type variables not having their symbol bound would mean that the later
pass for replacing type variables cannot detect them.

As an unintended side-effect of using `semGenericStmt`, unrelated
symbols are marked as used, which is what causes the different error
message in `tgeneric_backtrack_type_inference.nim` (the presence of the
`sfUsed` flag for generic parameters of routines decides whether a
routine is marked with `tfUnresolved`).

### Processing the generic expressions

For processing generic expressions used in the context of `static`
parameter inference, where unbound type variables are possible, the
`replaceTypeVarsInBody` procedure is introduced. While using 
`replaceTypesInBody` with `allowMetaTypes = true` would have sufficed,
this is intended as a step towards removing the "meta-types allowed"
mode from `semtypinst`.

Implementation-wise, `replaceTypeVarsInBody` is similar to
`prepareNode`,
with the differences being that `replaceTypeVarsInBody`:
- does not instantiates or traverses into any types
- only considers symbol nodes referring to type variables

Expression already having a type are not analyzed again when used as
call
operands, and thus two compromises are required for the
generic-expression
approach to work:
- both `prepareNode` and `replaceTypeVarsInBody` have to mirror
how `semSym` assigns types to symbol nodes of type variables (`fixType`
  implements this)
- `replaceTypeVarsInBody` has to remove from the expression the types
  previously assigned by both `semRangeAux` and `semArrayIndex`

`replaceTypesInBody` is renamed to `instantiateTypesInBody`. In
addition,
the unnecessarily exported `replaceTypeVarsN` is un-exported.

### Misc

- restore the name of the `tgenericshardcases` test, which was
  erroneously changed to `tsharedcases` during a test suite cleanup

---------

Co-authored-by: Saem Ghani <saemghani+github@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants