There's a lot of stuff wrong with the representation of these types:
TyFnDef doesn't actually uniquely identify a function, TyFnPtr is used to
represent method calls, TyFnDef in the sub-expression of a cast isn't
correctly reified, and probably some other stuff I haven't discovered yet.
Splitting them seems like the right first step, though.
Even after expansion, the generated expressions still track depth of
such pushes (i.e. how often you have "pushed" without a corresponding
"pop"), and we add a rule that in a context with a positive
`push_unsafe!` depth, it is effectively an `unsafe` block context.
(This way, we can inject code that uses `unsafe` features, but still
contains within it a sub-expression that should inherit the outer
safety checking setting, outside of the injected code.)
This is a total hack; it not only needs a feature-gate, but probably
should be feature-gated forever (if possible).
ignore-pretty in test/run-pass/pushpop-unsafe-okay.rs
`MethodCallee` now has no information about the method, other than its `DefId`.
The previous bits of information can be recovered as follows:
```rust
let method_item = tcx.impl_or_trait_item(callee.def_id);
let container = method_item.container();
```
The method is inherent if `container` is a `ty::ImplContainer`:
* the `impl` the method comes from is `container.id()`
The method is a trait method if `container` is a `ty::TraitContainer:
* the `trait` the method is part of is `container.id()`
* a `ty::TraitRef` can be constructed by putting together:
* `container.id()` as the `trait` ID
* `callee.substs.clone().method_to_trait()` as the `trait` substs (including `Self`)
* the above `trait_ref` is a valid `T: Trait<A, B, C>` predicate
* selecting `trait_ref` could result in one of the following:
* `traits::VtableImpl(data)`: static dispatch to `data.impl_def_id`
* `traits::VtableObject(data)`: dynamic dispatch, with the vtable index:
`traits::get_vtable_index_of_object_method(tcx, data, callee.def_id)`
* other variants of `traits::Vtable`: various other `impl` sources
This first patch starts by moving around pieces of state related to
type checking. The goal is to slowly unify the type checking state
into a single typing context. This initial patch moves the
ParameterEnvironment into the InferCtxt and moves shared tables
from Inherited and ty::ctxt into their own struct Tables. This
is the foundational work to refactoring the type checker to
enable future evolution of the language and tooling.
- add feature gate
- add basic tests
- adjust parser to eliminate conflict between `const fn` and associated
constants
- allow `const fn` in traits/trait-impls, but forbid later in type check
- correct some merge conflicts