More documentation
This commit is contained in:
parent
0f05b4be82
commit
41b0315f31
3 changed files with 38 additions and 1 deletions
|
@ -808,6 +808,23 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
/// Whether `anon_node_id` is a sibling or a child of a sibling of `def_id`
|
||||
///
|
||||
/// ```rust
|
||||
/// pub mod foo {
|
||||
/// pub mod bar {
|
||||
/// pub existential type Baz;
|
||||
///
|
||||
/// fn f1() -> Baz { .. }
|
||||
/// }
|
||||
///
|
||||
/// fn f2() -> bar::Baz { .. }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Here, `def_id` will be the `DefId` of the existential type `Baz`.
|
||||
/// `anon_node_id` is the `NodeId` of the reference to Baz -- so either the return type of f1 or f2.
|
||||
/// We will return true if the reference is within the same module as the existential type
|
||||
/// So true for f1, false for f2.
|
||||
pub fn may_define_existential_type(
|
||||
tcx: TyCtxt,
|
||||
def_id: DefId,
|
||||
|
|
|
@ -2861,7 +2861,7 @@ fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
def_id: DefId)
|
||||
-> ParamEnv<'tcx> {
|
||||
|
||||
// The param_env of an existential type is its parent's param_env
|
||||
// The param_env of an impl Trait type is its defining function's param_env
|
||||
if let Some(Def::Existential(_)) = tcx.describe_def(def_id) {
|
||||
if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
|
||||
if let hir::map::NodeItem(item) = tcx.hir.get(node_id) {
|
||||
|
|
|
@ -535,6 +535,26 @@ fn check_fn_or_method<'a, 'fcx, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
|||
check_where_clauses(tcx, fcx, span, def_id, Some(sig.output()));
|
||||
}
|
||||
|
||||
/// Checks "defining uses" of existential types to ensure that they meet the restrictions laid for
|
||||
/// "higher-order pattern unification".
|
||||
/// This ensures that inference is tractable.
|
||||
/// In particular, definitions of existential types can only use other generics as arguments,
|
||||
/// and they cannot repeat an argument. Example:
|
||||
///
|
||||
/// ```rust
|
||||
/// existential type Foo<A, B>;
|
||||
///
|
||||
/// // ok -- `Foo` is applied to two distinct, generic types.
|
||||
/// fn a<T, U>() -> Foo<T, U> { .. }
|
||||
///
|
||||
/// // not ok -- `Foo` is applied to `T` twice.
|
||||
/// fn b<T>() -> Foo<T, T> { .. }
|
||||
///
|
||||
///
|
||||
/// // not ok -- `Foo` is applied to a non-generic type.
|
||||
/// fn b<T>() -> Foo<T, u32> { .. }
|
||||
/// ```
|
||||
///
|
||||
fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
||||
fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue