int -> i32
This commit is contained in:
parent
c4840db8fc
commit
a24c8977ee
12 changed files with 45 additions and 43 deletions
|
@ -29,10 +29,10 @@ crate use self::util::elaborate_predicates;
|
||||||
|
|
||||||
pub use rustc_middle::traits::*;
|
pub use rustc_middle::traits::*;
|
||||||
|
|
||||||
/// An `Obligation` represents some trait reference (e.g., `int: Eq`) for
|
/// An `Obligation` represents some trait reference (e.g., `i32: Eq`) for
|
||||||
/// which the "impl_source" must be found. The process of finding a "impl_source" is
|
/// which the "impl_source" must be found. The process of finding a "impl_source" is
|
||||||
/// called "resolving" the `Obligation`. This process consists of
|
/// called "resolving" the `Obligation`. This process consists of
|
||||||
/// either identifying an `impl` (e.g., `impl Eq for int`) that
|
/// either identifying an `impl` (e.g., `impl Eq for i32`) that
|
||||||
/// satisfies the obligation, or else finding a bound that is in
|
/// satisfies the obligation, or else finding a bound that is in
|
||||||
/// scope. The eventual result is usually a `Selection` (defined below).
|
/// scope. The eventual result is usually a `Selection` (defined below).
|
||||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
|
|
|
@ -63,11 +63,11 @@ impl PredicateSet<'tcx> {
|
||||||
fn insert(&mut self, pred: ty::Predicate<'tcx>) -> bool {
|
fn insert(&mut self, pred: ty::Predicate<'tcx>) -> bool {
|
||||||
// We have to be careful here because we want
|
// We have to be careful here because we want
|
||||||
//
|
//
|
||||||
// for<'a> Foo<&'a int>
|
// for<'a> Foo<&'a i32>
|
||||||
//
|
//
|
||||||
// and
|
// and
|
||||||
//
|
//
|
||||||
// for<'b> Foo<&'b int>
|
// for<'b> Foo<&'b i32>
|
||||||
//
|
//
|
||||||
// to be considered equivalent. So normalize all late-bound
|
// to be considered equivalent. So normalize all late-bound
|
||||||
// regions before we throw things into the underlying set.
|
// regions before we throw things into the underlying set.
|
||||||
|
|
|
@ -393,23 +393,25 @@ pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
|
||||||
/// ```
|
/// ```
|
||||||
/// impl<T:Clone> Clone<T> for Option<T> { ... } // Impl_1
|
/// impl<T:Clone> Clone<T> for Option<T> { ... } // Impl_1
|
||||||
/// impl<T:Clone> Clone<T> for Box<T> { ... } // Impl_2
|
/// impl<T:Clone> Clone<T> for Box<T> { ... } // Impl_2
|
||||||
/// impl Clone for int { ... } // Impl_3
|
/// impl Clone for i32 { ... } // Impl_3
|
||||||
///
|
///
|
||||||
/// fn foo<T:Clone>(concrete: Option<Box<int>>,
|
/// fn foo<T: Clone>(concrete: Option<Box<i32>>, param: T, mixed: Option<T>) {
|
||||||
/// param: T,
|
/// // Case A: Vtable points at a specific impl. Only possible when
|
||||||
/// mixed: Option<T>) {
|
/// // type is concretely known. If the impl itself has bounded
|
||||||
|
/// // type parameters, Vtable will carry resolutions for those as well:
|
||||||
|
/// concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])])
|
||||||
///
|
///
|
||||||
/// // Case A: ImplSource points at a specific impl. Only possible when
|
/// // Case A: ImplSource points at a specific impl. Only possible when
|
||||||
/// // type is concretely known. If the impl itself has bounded
|
/// // type is concretely known. If the impl itself has bounded
|
||||||
/// // type parameters, ImplSource will carry resolutions for those as well:
|
/// // type parameters, ImplSource will carry resolutions for those as well:
|
||||||
/// concrete.clone(); // ImplSource(Impl_1, [ImplSource(Impl_2, [ImplSource(Impl_3)])])
|
/// concrete.clone(); // ImplSource(Impl_1, [ImplSource(Impl_2, [ImplSource(Impl_3)])])
|
||||||
///
|
///
|
||||||
/// // Case B: ImplSource must be provided by caller. This applies when
|
/// // Case B: ImplSource must be provided by caller. This applies when
|
||||||
/// // type is a type parameter.
|
/// // type is a type parameter.
|
||||||
/// param.clone(); // ImplSourceParam
|
/// param.clone(); // ImplSourceParam
|
||||||
///
|
///
|
||||||
/// // Case C: A mix of cases A and B.
|
/// // Case C: A mix of cases A and B.
|
||||||
/// mixed.clone(); // ImplSource(Impl_1, [ImplSourceParam])
|
/// mixed.clone(); // ImplSource(Impl_1, [ImplSourceParam])
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
|
|
@ -599,12 +599,12 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// type Func<A> = fn(A);
|
/// type Func<A> = fn(A);
|
||||||
/// type MetaFunc = for<'a> fn(Func<&'a int>)
|
/// type MetaFunc = for<'a> fn(Func<&'a i32>)
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// The type `MetaFunc`, when fully expanded, will be
|
/// The type `MetaFunc`, when fully expanded, will be
|
||||||
///
|
///
|
||||||
/// for<'a> fn(fn(&'a int))
|
/// for<'a> fn(fn(&'a i32))
|
||||||
/// ^~ ^~ ^~~
|
/// ^~ ^~ ^~~
|
||||||
/// | | |
|
/// | | |
|
||||||
/// | | DebruijnIndex of 2
|
/// | | DebruijnIndex of 2
|
||||||
|
@ -613,7 +613,7 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
|
||||||
/// Here the `'a` lifetime is bound in the outer function, but appears as an argument of the
|
/// Here the `'a` lifetime is bound in the outer function, but appears as an argument of the
|
||||||
/// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip
|
/// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip
|
||||||
/// over the inner binder (remember that we count De Bruijn indices from 1). However, in the
|
/// over the inner binder (remember that we count De Bruijn indices from 1). However, in the
|
||||||
/// definition of `MetaFunc`, the binder is not visible, so the type `&'a int` will have a
|
/// definition of `MetaFunc`, the binder is not visible, so the type `&'a i32` will have a
|
||||||
/// De Bruijn index of 1. It's only during the substitution that we can see we must increase the
|
/// De Bruijn index of 1. It's only during the substitution that we can see we must increase the
|
||||||
/// depth by 1 to account for the binder that we passed through.
|
/// depth by 1 to account for the binder that we passed through.
|
||||||
///
|
///
|
||||||
|
@ -621,18 +621,18 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// type FuncTuple<A> = (A,fn(A));
|
/// type FuncTuple<A> = (A,fn(A));
|
||||||
/// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a int>)
|
/// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a i32>)
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Here the final type will be:
|
/// Here the final type will be:
|
||||||
///
|
///
|
||||||
/// for<'a> fn((&'a int, fn(&'a int)))
|
/// for<'a> fn((&'a i32, fn(&'a i32)))
|
||||||
/// ^~~ ^~~
|
/// ^~~ ^~~
|
||||||
/// | |
|
/// | |
|
||||||
/// DebruijnIndex of 1 |
|
/// DebruijnIndex of 1 |
|
||||||
/// DebruijnIndex of 2
|
/// DebruijnIndex of 2
|
||||||
///
|
///
|
||||||
/// As indicated in the diagram, here the same type `&'a int` is substituted once, but in the
|
/// As indicated in the diagram, here the same type `&'a i32` is substituted once, but in the
|
||||||
/// first case we do not increase the De Bruijn index and in the second case we do. The reason
|
/// first case we do not increase the De Bruijn index and in the second case we do. The reason
|
||||||
/// is that only in the second case have we passed through a fn binder.
|
/// is that only in the second case have we passed through a fn binder.
|
||||||
fn shift_vars_through_binders<T: TypeFoldable<'tcx>>(&self, val: T) -> T {
|
fn shift_vars_through_binders<T: TypeFoldable<'tcx>>(&self, val: T) -> T {
|
||||||
|
|
|
@ -22,13 +22,13 @@ impl<'tcx> TypeWalker<'tcx> {
|
||||||
/// Skips the subtree corresponding to the last type
|
/// Skips the subtree corresponding to the last type
|
||||||
/// returned by `next()`.
|
/// returned by `next()`.
|
||||||
///
|
///
|
||||||
/// Example: Imagine you are walking `Foo<Bar<int>, usize>`.
|
/// Example: Imagine you are walking `Foo<Bar<i32>, usize>`.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let mut iter: TypeWalker = ...;
|
/// let mut iter: TypeWalker = ...;
|
||||||
/// iter.next(); // yields Foo
|
/// iter.next(); // yields Foo
|
||||||
/// iter.next(); // yields Bar<int>
|
/// iter.next(); // yields Bar<i32>
|
||||||
/// iter.skip_current_subtree(); // skips int
|
/// iter.skip_current_subtree(); // skips i32
|
||||||
/// iter.next(); // yields usize
|
/// iter.next(); // yields usize
|
||||||
/// ```
|
/// ```
|
||||||
pub fn skip_current_subtree(&mut self) {
|
pub fn skip_current_subtree(&mut self) {
|
||||||
|
|
|
@ -361,7 +361,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||||
// handle normalization within binders because
|
// handle normalization within binders because
|
||||||
// otherwise we wind up a need to normalize when doing
|
// otherwise we wind up a need to normalize when doing
|
||||||
// trait matching (since you can have a trait
|
// trait matching (since you can have a trait
|
||||||
// obligation like `for<'a> T::B : Fn(&'a int)`), but
|
// obligation like `for<'a> T::B: Fn(&'a i32)`), but
|
||||||
// we can't normalize with bound regions in scope. So
|
// we can't normalize with bound regions in scope. So
|
||||||
// far now we just ignore binders but only normalize
|
// far now we just ignore binders but only normalize
|
||||||
// if all bound regions are gone (and then we still
|
// if all bound regions are gone (and then we still
|
||||||
|
|
|
@ -145,7 +145,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
// handle normalization within binders because
|
// handle normalization within binders because
|
||||||
// otherwise we wind up a need to normalize when doing
|
// otherwise we wind up a need to normalize when doing
|
||||||
// trait matching (since you can have a trait
|
// trait matching (since you can have a trait
|
||||||
// obligation like `for<'a> T::B : Fn(&'a int)`), but
|
// obligation like `for<'a> T::B: Fn(&'a i32)`), but
|
||||||
// we can't normalize with bound regions in scope. So
|
// we can't normalize with bound regions in scope. So
|
||||||
// far now we just ignore binders but only normalize
|
// far now we just ignore binders but only normalize
|
||||||
// if all bound regions are gone (and then we still
|
// if all bound regions are gone (and then we still
|
||||||
|
|
|
@ -553,14 +553,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
///
|
///
|
||||||
/// Here is an example. Imagine we have a closure expression
|
/// Here is an example. Imagine we have a closure expression
|
||||||
/// and we desugared it so that the type of the expression is
|
/// and we desugared it so that the type of the expression is
|
||||||
/// `Closure`, and `Closure` expects an int as argument. Then it
|
/// `Closure`, and `Closure` expects `i32` as argument. Then it
|
||||||
/// is "as if" the compiler generated this impl:
|
/// is "as if" the compiler generated this impl:
|
||||||
///
|
///
|
||||||
/// impl Fn(int) for Closure { ... }
|
/// impl Fn(i32) for Closure { ... }
|
||||||
///
|
///
|
||||||
/// Now imagine our obligation is `Fn(usize) for Closure`. So far
|
/// Now imagine our obligation is `Closure: Fn(usize)`. So far
|
||||||
/// we have matched the self type `Closure`. At this point we'll
|
/// we have matched the self type `Closure`. At this point we'll
|
||||||
/// compare the `int` to `usize` and generate an error.
|
/// compare the `i32` to `usize` and generate an error.
|
||||||
///
|
///
|
||||||
/// Note that this checking occurs *after* the impl has selected,
|
/// Note that this checking occurs *after* the impl has selected,
|
||||||
/// because these output type parameters should not affect the
|
/// because these output type parameters should not affect the
|
||||||
|
|
|
@ -1762,7 +1762,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// The strategy is to:
|
// The strategy is to:
|
||||||
//
|
//
|
||||||
// 1. Instantiate those regions to placeholder regions (e.g.,
|
// 1. Instantiate those regions to placeholder regions (e.g.,
|
||||||
// `for<'a> &'a int` becomes `&0 i32`.
|
// `for<'a> &'a i32` becomes `&0 i32`.
|
||||||
// 2. Produce something like `&'0 i32 : Copy`
|
// 2. Produce something like `&'0 i32 : Copy`
|
||||||
// 3. Re-bind the regions back to `for<'a> &'a i32 : Copy`
|
// 3. Re-bind the regions back to `for<'a> &'a i32 : Copy`
|
||||||
|
|
||||||
|
|
|
@ -1394,13 +1394,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// That is, consider this case:
|
// That is, consider this case:
|
||||||
//
|
//
|
||||||
// ```
|
// ```
|
||||||
// trait SubTrait: SuperTrait<int> { }
|
// trait SubTrait: SuperTrait<i32> { }
|
||||||
// trait SuperTrait<A> { type T; }
|
// trait SuperTrait<A> { type T; }
|
||||||
//
|
//
|
||||||
// ... B: SubTrait<T = foo> ...
|
// ... B: SubTrait<T = foo> ...
|
||||||
// ```
|
// ```
|
||||||
//
|
//
|
||||||
// We want to produce `<B as SuperTrait<int>>::T == foo`.
|
// We want to produce `<B as SuperTrait<i32>>::T == foo`.
|
||||||
|
|
||||||
// Find any late-bound regions declared in `ty` that are not
|
// Find any late-bound regions declared in `ty` that are not
|
||||||
// declared in the trait-ref. These are not well-formed.
|
// declared in the trait-ref. These are not well-formed.
|
||||||
|
|
|
@ -1468,7 +1468,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// trait Foo { ... }
|
/// trait Foo { ... }
|
||||||
/// impl Foo for Vec<int> { ... }
|
/// impl Foo for Vec<i32> { ... }
|
||||||
/// impl Foo for Vec<usize> { ... }
|
/// impl Foo for Vec<usize> { ... }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
|
|
@ -212,7 +212,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// errors in some cases, such as this one:
|
// errors in some cases, such as this one:
|
||||||
//
|
//
|
||||||
// ```
|
// ```
|
||||||
// fn foo<'x>(x: &'x int) {
|
// fn foo<'x>(x: &'x i32) {
|
||||||
// let a = 1;
|
// let a = 1;
|
||||||
// let mut z = x;
|
// let mut z = x;
|
||||||
// z = &a;
|
// z = &a;
|
||||||
|
@ -220,7 +220,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// ```
|
// ```
|
||||||
//
|
//
|
||||||
// The reason we might get an error is that `z` might be
|
// The reason we might get an error is that `z` might be
|
||||||
// assigned a type like `&'x int`, and then we would have
|
// assigned a type like `&'x i32`, and then we would have
|
||||||
// a problem when we try to assign `&a` to `z`, because
|
// a problem when we try to assign `&a` to `z`, because
|
||||||
// the lifetime of `&a` (i.e., the enclosing block) is
|
// the lifetime of `&a` (i.e., the enclosing block) is
|
||||||
// shorter than `'x`.
|
// shorter than `'x`.
|
||||||
|
@ -229,11 +229,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// expected type here is whatever type the user wrote, not
|
// expected type here is whatever type the user wrote, not
|
||||||
// the initializer's type. In this case the user wrote
|
// the initializer's type. In this case the user wrote
|
||||||
// nothing, so we are going to create a type variable `Z`.
|
// nothing, so we are going to create a type variable `Z`.
|
||||||
// Then we will assign the type of the initializer (`&'x
|
// Then we will assign the type of the initializer (`&'x i32`)
|
||||||
// int`) as a subtype of `Z`: `&'x int <: Z`. And hence we
|
// as a subtype of `Z`: `&'x i32 <: Z`. And hence we
|
||||||
// will instantiate `Z` as a type `&'0 int` where `'0` is
|
// will instantiate `Z` as a type `&'0 i32` where `'0` is
|
||||||
// a fresh region variable, with the constraint that `'x :
|
// a fresh region variable, with the constraint that `'x : '0`.
|
||||||
// '0`. So basically we're all set.
|
// So basically we're all set.
|
||||||
//
|
//
|
||||||
// Note that there are two tests to check that this remains true
|
// Note that there are two tests to check that this remains true
|
||||||
// (`regions-reassign-{match,let}-bound-pointer.rs`).
|
// (`regions-reassign-{match,let}-bound-pointer.rs`).
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue