about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-09-15 06:25:38 +0000
committerbors <bors@rust-lang.org>2015-09-15 06:25:38 +0000
commita7b3eed7505d913788b18cac60097345ef21902e (patch)
tree27087216552b603fa70378bb4ddaa3458632e5f6 /src
parentf3e6d315386cebdd6679055d9350c258f2a51689 (diff)
parent4fec679399ddaf67d15adddad2677731f94dfa36 (diff)
downloadrust-a7b3eed7505d913788b18cac60097345ef21902e.tar.gz
rust-a7b3eed7505d913788b18cac60097345ef21902e.zip
Auto merge of #28395 - ebfull:fix-associated-item-resolution, r=arielb1
Fixes #28344
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/astconv.rs55
-rw-r--r--src/test/compile-fail/issue-28344.rs21
-rw-r--r--src/test/compile-fail/unspecified-self-in-trait-ref.rs30
3 files changed, 94 insertions, 12 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 80994632c52..971ca329e6b 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -407,18 +407,13 @@ fn create_substs_for_ast_path<'tcx>(
                                                .take_while(|x| x.default.is_none())
                                                .count();
 
-    // Fill with `ty_infer` if no params were specified, as long as
-    // they were optional (e.g. paths inside expressions).
-    let mut type_substs = if param_mode == PathParamMode::Optional &&
-                             types_provided.is_empty() {
-        let mut substs = region_substs.clone();
-        ty_param_defs
-            .iter()
-            .map(|p| this.ty_infer(Some(p.clone()), Some(&mut substs), Some(TypeSpace), span))
-            .collect()
-    } else {
-        types_provided
-    };
+    let mut type_substs = get_type_substs_for_defs(this,
+                                                   span,
+                                                   types_provided,
+                                                   param_mode,
+                                                   ty_param_defs,
+                                                   region_substs.clone(),
+                                                   self_ty);
 
     let supplied_ty_param_count = type_substs.len();
     check_type_argument_count(this.tcx(), span, supplied_ty_param_count,
@@ -482,6 +477,42 @@ fn create_substs_for_ast_path<'tcx>(
     substs
 }
 
+/// Returns types_provided if it is not empty, otherwise populating the
+/// type parameters with inference variables as appropriate.
+fn get_type_substs_for_defs<'tcx>(this: &AstConv<'tcx>,
+                                  span: Span,
+                                  types_provided: Vec<Ty<'tcx>>,
+                                  param_mode: PathParamMode,
+                                  ty_param_defs: &[ty::TypeParameterDef<'tcx>],
+                                  mut substs: Substs<'tcx>,
+                                  self_ty: Option<Ty<'tcx>>)
+                                  -> Vec<Ty<'tcx>>
+{
+    fn default_type_parameter<'tcx>(p: &ty::TypeParameterDef<'tcx>, self_ty: Option<Ty<'tcx>>)
+                                    -> Option<ty::TypeParameterDef<'tcx>>
+    {
+        if let Some(ref default) = p.default {
+            if self_ty.is_none() && default.has_self_ty() {
+                // There is no suitable inference default for a type parameter
+                // that references self with no self-type provided.
+                return None;
+            }
+        }
+
+        Some(p.clone())
+    }
+
+    if param_mode == PathParamMode::Optional && types_provided.is_empty() {
+        ty_param_defs
+            .iter()
+            .map(|p| this.ty_infer(default_type_parameter(p, self_ty), Some(&mut substs),
+                                   Some(TypeSpace), span))
+            .collect()
+    } else {
+        types_provided
+    }
+}
+
 struct ConvertedBinding<'tcx> {
     item_name: ast::Name,
     ty: Ty<'tcx>,
diff --git a/src/test/compile-fail/issue-28344.rs b/src/test/compile-fail/issue-28344.rs
new file mode 100644
index 00000000000..751a42826d2
--- /dev/null
+++ b/src/test/compile-fail/issue-28344.rs
@@ -0,0 +1,21 @@
+// Copyright 2015 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.
+
+use std::ops::BitXor;
+
+fn main() {
+    let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
+    //~^ ERROR must be specified
+    //~| no associated item named
+
+    let g = BitXor::bitor;
+    //~^ ERROR must be specified
+    //~| no associated item named
+}
\ No newline at end of file
diff --git a/src/test/compile-fail/unspecified-self-in-trait-ref.rs b/src/test/compile-fail/unspecified-self-in-trait-ref.rs
new file mode 100644
index 00000000000..2c2f113a779
--- /dev/null
+++ b/src/test/compile-fail/unspecified-self-in-trait-ref.rs
@@ -0,0 +1,30 @@
+// Copyright 2015 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.
+
+pub trait Foo<A=Self> {
+    fn foo();
+}
+
+pub trait Bar<X=usize, A=Self> {
+    fn foo();
+}
+
+fn main() {
+    let a = Foo::lol();
+    //~^ ERROR no associated item named
+    let b = Foo::<_>::lol();
+    //~^ ERROR no associated item named
+    let c = Bar::lol();
+    //~^ ERROR no associated item named
+    let d = Bar::<usize, _>::lol();
+    //~^ ERROR no associated item named
+    let e = Bar::<usize>::lol();
+    //~^ ERROR must be explicitly specified
+}