Skip to content

Commit

Permalink
Auto merge of #28395 - ebfull:fix-associated-item-resolution, r=arielb1
Browse files Browse the repository at this point in the history
Fixes #28344
  • Loading branch information
bors committed Sep 15, 2015
2 parents f3e6d31 + 4fec679 commit a7b3eed
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 12 deletions.
55 changes: 43 additions & 12 deletions src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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>,
Expand Down
21 changes: 21 additions & 0 deletions src/test/compile-fail/issue-28344.rs
Original file line number Diff line number Diff line change
@@ -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
}
30 changes: 30 additions & 0 deletions src/test/compile-fail/unspecified-self-in-trait-ref.rs
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit a7b3eed

Please sign in to comment.