]> git.lizzy.rs Git - rust.git/commitdiff
Address nits.
authorNiko Matsakis <niko@alum.mit.edu>
Tue, 30 Dec 2014 13:59:33 +0000 (08:59 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Tue, 30 Dec 2014 14:36:23 +0000 (09:36 -0500)
14 files changed:
src/librustc/middle/traits/fulfill.rs
src/librustc/middle/traits/mod.rs
src/librustc/middle/traits/project.rs
src/librustc/middle/traits/select.rs
src/librustc/middle/traits/util.rs
src/librustc/middle/ty.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/assoc.rs
src/librustc_typeck/check/mod.rs
src/test/auxiliary/associated-types-cc-lib.rs [new file with mode: 0644]
src/test/auxiliary/issue-18048-lib.rs [deleted file]
src/test/run-pass/associated-types-cc.rs [new file with mode: 0644]
src/test/run-pass/issue-18048.rs [deleted file]
src/test/run-pass/issue-19081.rs

index b55504da237afcf198e5d774d8f10e98bec3fdf0..7ec221fcfa9037c7a591cf9410eb156ecead367c 100644 (file)
@@ -14,7 +14,6 @@
 use std::collections::HashSet;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::default::Default;
-use std::rc::Rc;
 use syntax::ast;
 use util::common::ErrorReported;
 use util::ppaux::Repr;
@@ -102,26 +101,30 @@ pub fn new() -> FulfillmentContext<'tcx> {
         }
     }
 
-    pub fn normalize_associated_type<'a>(&mut self,
+    /// "Normalize" a projection type `<SomeType as SomeTrait>::X` by
+    /// creating a fresh type variable `$0` as well as a projection
+    /// predicate `<SomeType as SomeTrait>::X == $0`. When the
+    /// inference engine runs, it will attempt to find an impl of
+    /// `SomeTrait` or a where clause that lets us unify `$0` with
+    /// something concrete. If this fails, we'll unify `$0` with
+    /// `projection_ty` again.
+    pub fn normalize_projection_type<'a>(&mut self,
                                          infcx: &InferCtxt<'a,'tcx>,
-                                         trait_ref: Rc<ty::TraitRef<'tcx>>,
-                                         item_name: ast::Name,
+                                         projection_ty: ty::ProjectionTy<'tcx>,
                                          cause: ObligationCause<'tcx>)
                                          -> Ty<'tcx>
     {
-        debug!("normalize_associated_type(trait_ref={}, item_name={})",
-               trait_ref.repr(infcx.tcx),
-               item_name.repr(infcx.tcx));
+        debug!("normalize_associated_type(projection_ty={})",
+               projection_ty.repr(infcx.tcx));
 
-        assert!(!trait_ref.has_escaping_regions());
+        assert!(!projection_ty.has_escaping_regions());
 
         // FIXME(#20304) -- cache
 
         let ty_var = infcx.next_ty_var();
         let projection =
             ty::Binder(ty::ProjectionPredicate {
-                projection_ty: ty::ProjectionTy { trait_ref: trait_ref,
-                                                  item_name: item_name },
+                projection_ty: projection_ty,
                 ty: ty_var
             });
         let obligation = Obligation::new(cause, projection.as_predicate());
index d7febea8909b174a26edb6f8db001dea2fa46e91..d4fa0c98ad5d14d348e222d85983999bd931cfdd 100644 (file)
@@ -117,7 +117,10 @@ pub enum ObligationCauseCode<'tcx> {
 
 #[deriving(Clone)]
 pub struct DerivedObligationCause<'tcx> {
-    /// Resolving this trait led to the current obligation
+    /// The trait reference of the parent obligation that led to the
+    /// current obligation. Note that only trait obligations lead to
+    /// derived obligations, so we just store the trait reference here
+    /// directly.
     parent_trait_ref: ty::PolyTraitRef<'tcx>,
 
     /// The parent trait had this cause
index d319e441415197f6deb597afbcd2d78d156796b7..435babf168e86d79abd53f6218469c67e5d7e4a6 100644 (file)
@@ -20,7 +20,6 @@
 use middle::infer;
 use middle::subst::Subst;
 use middle::ty::{mod, AsPredicate, ToPolyTraitRef, Ty};
-use std::fmt;
 use util::ppaux::Repr;
 
 pub type PolyProjectionObligation<'tcx> =
 
 /// When attempting to resolve `<T as TraitRef>::Name == U`...
 pub enum ProjectionError<'tcx> {
+    /// ...we could not find any helpful information on what `Name`
+    /// might be. This could occur, for example, if there is a where
+    /// clause `T : TraitRef` but not `T : TraitRef<Name=V>`. When
+    /// normalizing, this case is where we opt to normalize back to
+    /// the projection type `<T as TraitRef>::Name`.
     NoCandidate,
+
+    /// ...we found multiple sources of information and couldn't resolve the ambiguity.
     TooManyCandidates,
 
-    ///
+    /// ...`<T as TraitRef::Name>` ws resolved to some type `V` that failed to unify with `U`
     MismatchedTypes(MismatchedProjectionTypes<'tcx>),
 
     /// ...an error occurred matching `T : TraitRef`
@@ -380,12 +386,6 @@ fn confirm_candidate<'cx,'tcx>(
     Ok(projected_ty)
 }
 
-impl<'tcx> Repr<'tcx> for super::MismatchedProjectionTypes<'tcx> {
-    fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
-        self.err.repr(tcx)
-    }
-}
-
 impl<'tcx> Repr<'tcx> for ProjectionError<'tcx> {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         match *self {
@@ -401,12 +401,6 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
     }
 }
 
-impl<'tcx> fmt::Show for super::MismatchedProjectionTypes<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "MismatchedProjectionTypes(..)")
-    }
-}
-
 impl<'tcx> Repr<'tcx> for ProjectionTyCandidate<'tcx> {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         match *self {
index 755e50f13275edbda20c7f7abd95ac51109ed6cb..ce5337a58e10c102bab3fde612f46eb4659cb613 100644 (file)
@@ -150,8 +150,15 @@ enum SelectionCandidate<'tcx> {
 }
 
 struct SelectionCandidateSet<'tcx> {
+    // a list of candidates that definitely apply to the current
+    // obligation (meaning: types unify).
     vec: Vec<SelectionCandidate<'tcx>>,
-    ambiguous: bool
+
+    // if this is true, then there were candidates that might or might
+    // not have applied, but we couldn't tell. This occurs when some
+    // of the input types are type variables, in which case there are
+    // various "builtin" rules that might or might not trigger.
+    ambiguous: bool,
 }
 
 enum BuiltinBoundConditions<'tcx> {
index ddf2c9d87fee235d5a7291313cfe6f5a27277c3d..109810fc7eec3efacb5bea0a141b1087fafe8544 100644 (file)
@@ -385,9 +385,16 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<'tcx> Repr<'tcx> for ty::type_err<'tcx> {
+impl<'tcx> Repr<'tcx> for super::MismatchedProjectionTypes<'tcx> {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
-        ty::type_err_to_str(tcx, self)
+        self.err.repr(tcx)
     }
 }
 
+impl<'tcx> fmt::Show for super::MismatchedProjectionTypes<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "MismatchedProjectionTypes(..)")
+    }
+}
+
+
index d6ab0201d190a22b0cbc00feef3f0668bbe03000..ab39c761a3861ce644a2598acc31248a20bef5c6 100644 (file)
@@ -1791,7 +1791,8 @@ pub enum Predicate<'tcx> {
     /// where T : 'a
     TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
 
-    ///
+    /// where <T as TraitRef>::Name == X, approximately.
+    /// See `ProjectionPredicate` struct for details.
     Projection(PolyProjectionPredicate<'tcx>),
 }
 
@@ -1857,9 +1858,14 @@ pub fn sort_key(&self) -> (ast::DefId, ast::Name) {
     }
 }
 
+/// Represents the projection of an associated type. In explicit UFCS
+/// form this would be written `<T as Trait<..>>::N`.
 #[deriving(Clone, PartialEq, Eq, Hash, Show)]
 pub struct ProjectionTy<'tcx> {
+    /// The trait reference `T as Trait<..>`.
     pub trait_ref: Rc<ty::TraitRef<'tcx>>,
+
+    /// The name `N` of the associated type.
     pub item_name: ast::Name,
 }
 
@@ -2179,6 +2185,12 @@ pub fn for_item(cx: &ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'tcx> {
 /// - `generics`: the set of type parameters and their bounds
 /// - `ty`: the base types, which may reference the parameters defined
 ///   in `generics`
+///
+/// Note that TypeSchemes are also sometimes called "polytypes" (and
+/// in fact this struct used to carry that name, so you may find some
+/// stray references in a comment or something). We try to reserve the
+/// "poly" prefix to refer to higher-ranked things, as in
+/// `PolyTraitRef`.
 #[deriving(Clone, Show)]
 pub struct TypeScheme<'tcx> {
     pub generics: Generics<'tcx>,
@@ -4680,6 +4692,12 @@ pub fn ty_sort_string<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> String {
     }
 }
 
+impl<'tcx> Repr<'tcx> for ty::type_err<'tcx> {
+    fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
+        ty::type_err_to_str(tcx, self)
+    }
+}
+
 /// Explains the source of a type err in a short, human readable way. This is meant to be placed
 /// in parentheses after some larger message. You should also invoke `note_and_explain_type_err()`
 /// afterwards to present additional details, particularly when it comes to lifetime-related
index 82a023202097f4ab76ce57c74245cbec22921746..587a85cfcbac4cd7e9d93960aad02260ce026397 100644 (file)
@@ -244,7 +244,6 @@ pub fn opt_ast_region_to_region<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
 fn ast_path_substs_for_ty<'tcx,AC,RS>(
     this: &AC,
     rscope: &RS,
-    decl_def_id: ast::DefId,
     decl_generics: &ty::Generics<'tcx>,
     path: &ast::Path)
     -> Substs<'tcx>
@@ -280,7 +279,6 @@ fn ast_path_substs_for_ty<'tcx,AC,RS>(
     create_substs_for_ast_path(this,
                                rscope,
                                path.span,
-                               decl_def_id,
                                decl_generics,
                                None,
                                types,
@@ -291,7 +289,6 @@ fn create_substs_for_ast_path<'tcx,AC,RS>(
     this: &AC,
     rscope: &RS,
     span: Span,
-    _decl_def_id: ast::DefId,
     decl_generics: &ty::Generics<'tcx>,
     self_ty: Option<Ty<'tcx>>,
     types: Vec<Ty<'tcx>>,
@@ -621,7 +618,6 @@ fn ast_path_to_trait_ref<'a,'tcx,AC,RS>(
     let substs = create_substs_for_ast_path(this,
                                             &shifted_rscope,
                                             path.span,
-                                            trait_def_id,
                                             &trait_def.generics,
                                             self_ty,
                                             types,
@@ -705,7 +701,6 @@ pub fn ast_path_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
 
     let substs = ast_path_substs_for_ty(this,
                                         rscope,
-                                        did,
                                         &generics,
                                         path);
     let ty = decl_ty.subst(tcx, &substs);
@@ -747,7 +742,7 @@ pub fn ast_path_to_ty_relaxed<'tcx,AC,RS>(
         Substs::new(VecPerParamSpace::params_from_type(type_params),
                     VecPerParamSpace::params_from_type(region_params))
     } else {
-        ast_path_substs_for_ty(this, rscope, did, &generics, path)
+        ast_path_substs_for_ty(this, rscope, &generics, path)
     };
 
     let ty = decl_ty.subst(tcx, &substs);
index 0d7ce2f871a6fd6d21d62ef7c96058e08c9469aa..081959a4efa4a9f8e64255d4355bfd4a26887867 100644 (file)
@@ -80,11 +80,9 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                         self.span,
                         self.body_id,
                         ObligationCauseCode::MiscObligation);
-                let trait_ref = data.trait_ref.clone();
                 self.fulfillment_cx
-                    .normalize_associated_type(self.infcx,
-                                               trait_ref,
-                                               data.item_name,
+                    .normalize_projection_type(self.infcx,
+                                               data.clone(),
                                                cause)
             }
             _ => {
index 7929a005af2c8a937795c4be93239af6bded9cd9..12ecfe6c2981c0b6075ecaa0fe2cea0019c59151 100644 (file)
@@ -1758,9 +1758,11 @@ fn normalize_associated_type(&self,
                                                  traits::ObligationCauseCode::MiscObligation);
         self.inh.fulfillment_cx
             .borrow_mut()
-            .normalize_associated_type(self.infcx(),
-                                       trait_ref,
-                                       item_name,
+            .normalize_projection_type(self.infcx(),
+                                       ty::ProjectionTy {
+                                           trait_ref: trait_ref,
+                                           item_name: item_name,
+                                       },
                                        cause)
     }
 
diff --git a/src/test/auxiliary/associated-types-cc-lib.rs b/src/test/auxiliary/associated-types-cc-lib.rs
new file mode 100644 (file)
index 0000000..17b2a07
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Helper for test issue-18048, which tests associated types in a
+// cross-crate scenario.
+
+#![crate_type="lib"]
+#![feature(associated_types)]
+
+pub trait Bar {
+    type T;
+
+    fn get(x: Option<Self>) -> <Self as Bar>::T;
+}
+
+impl Bar for int {
+    type T = uint;
+
+    fn get(_: Option<int>) -> uint { 22 }
+}
diff --git a/src/test/auxiliary/issue-18048-lib.rs b/src/test/auxiliary/issue-18048-lib.rs
deleted file mode 100644 (file)
index 52cc216..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_type="lib"]
-#![feature(associated_types)]
-
-pub trait Bar {
-    type T;
-
-    fn get(x: Option<Self>) -> <Self as Bar>::T;
-}
-
-impl Bar for int {
-    type T = uint;
-
-    fn get(_: Option<int>) -> uint { 22 }
-}
diff --git a/src/test/run-pass/associated-types-cc.rs b/src/test/run-pass/associated-types-cc.rs
new file mode 100644 (file)
index 0000000..c0cf917
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:associated-types-cc-lib.rs
+
+// Test that we are able to reference cross-crate traits that employ
+// associated types.
+
+#![feature(associated_types)]
+
+extern crate "associated-types-cc-lib" as bar;
+
+use bar::Bar;
+
+fn foo<B:Bar>(b: B) -> <B as Bar>::T {
+    Bar::get(None::<B>)
+}
+
+fn main() {
+    println!("{}", foo(3i));
+}
diff --git a/src/test/run-pass/issue-18048.rs b/src/test/run-pass/issue-18048.rs
deleted file mode 100644 (file)
index 7cd6e5e..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:issue-18048-lib.rs
-
-// Test that we are able to reference cross-crate traits that employ
-// associated types.
-
-#![feature(associated_types)]
-
-extern crate "issue-18048-lib" as bar;
-
-use bar::Bar;
-
-fn foo<B:Bar>(b: B) -> <B as Bar>::T {
-    Bar::get(None::<B>)
-}
-
-fn main() {
-    println!("{}", foo(3i));
-}
index aeb140874779d6c8590605c0297c76b9a64ac40b..57724ba91b02f317e9a3e05ef067d7596f4143be 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-pretty -- currently pretty prints as `Hash<<Self as Hasher...` which fails to parse
+// ignore-pretty -- FIXME(#17362) pretty prints as `Hash<<Self as Hasher...` which fails to parse
 
 #![feature(associated_types)]