Skip to content

Commit a7b3eed

Browse files
committed
Auto merge of #28395 - ebfull:fix-associated-item-resolution, r=arielb1
Fixes #28344
2 parents f3e6d31 + 4fec679 commit a7b3eed

File tree

3 files changed

+94
-12
lines changed

3 files changed

+94
-12
lines changed

src/librustc_typeck/astconv.rs

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -407,18 +407,13 @@ fn create_substs_for_ast_path<'tcx>(
407407
.take_while(|x| x.default.is_none())
408408
.count();
409409

410-
// Fill with `ty_infer` if no params were specified, as long as
411-
// they were optional (e.g. paths inside expressions).
412-
let mut type_substs = if param_mode == PathParamMode::Optional &&
413-
types_provided.is_empty() {
414-
let mut substs = region_substs.clone();
415-
ty_param_defs
416-
.iter()
417-
.map(|p| this.ty_infer(Some(p.clone()), Some(&mut substs), Some(TypeSpace), span))
418-
.collect()
419-
} else {
420-
types_provided
421-
};
410+
let mut type_substs = get_type_substs_for_defs(this,
411+
span,
412+
types_provided,
413+
param_mode,
414+
ty_param_defs,
415+
region_substs.clone(),
416+
self_ty);
422417

423418
let supplied_ty_param_count = type_substs.len();
424419
check_type_argument_count(this.tcx(), span, supplied_ty_param_count,
@@ -482,6 +477,42 @@ fn create_substs_for_ast_path<'tcx>(
482477
substs
483478
}
484479

480+
/// Returns types_provided if it is not empty, otherwise populating the
481+
/// type parameters with inference variables as appropriate.
482+
fn get_type_substs_for_defs<'tcx>(this: &AstConv<'tcx>,
483+
span: Span,
484+
types_provided: Vec<Ty<'tcx>>,
485+
param_mode: PathParamMode,
486+
ty_param_defs: &[ty::TypeParameterDef<'tcx>],
487+
mut substs: Substs<'tcx>,
488+
self_ty: Option<Ty<'tcx>>)
489+
-> Vec<Ty<'tcx>>
490+
{
491+
fn default_type_parameter<'tcx>(p: &ty::TypeParameterDef<'tcx>, self_ty: Option<Ty<'tcx>>)
492+
-> Option<ty::TypeParameterDef<'tcx>>
493+
{
494+
if let Some(ref default) = p.default {
495+
if self_ty.is_none() && default.has_self_ty() {
496+
// There is no suitable inference default for a type parameter
497+
// that references self with no self-type provided.
498+
return None;
499+
}
500+
}
501+
502+
Some(p.clone())
503+
}
504+
505+
if param_mode == PathParamMode::Optional && types_provided.is_empty() {
506+
ty_param_defs
507+
.iter()
508+
.map(|p| this.ty_infer(default_type_parameter(p, self_ty), Some(&mut substs),
509+
Some(TypeSpace), span))
510+
.collect()
511+
} else {
512+
types_provided
513+
}
514+
}
515+
485516
struct ConvertedBinding<'tcx> {
486517
item_name: ast::Name,
487518
ty: Ty<'tcx>,

src/test/compile-fail/issue-28344.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::ops::BitXor;
12+
13+
fn main() {
14+
let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
15+
//~^ ERROR must be specified
16+
//~| no associated item named
17+
18+
let g = BitXor::bitor;
19+
//~^ ERROR must be specified
20+
//~| no associated item named
21+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub trait Foo<A=Self> {
12+
fn foo();
13+
}
14+
15+
pub trait Bar<X=usize, A=Self> {
16+
fn foo();
17+
}
18+
19+
fn main() {
20+
let a = Foo::lol();
21+
//~^ ERROR no associated item named
22+
let b = Foo::<_>::lol();
23+
//~^ ERROR no associated item named
24+
let c = Bar::lol();
25+
//~^ ERROR no associated item named
26+
let d = Bar::<usize, _>::lol();
27+
//~^ ERROR no associated item named
28+
let e = Bar::<usize>::lol();
29+
//~^ ERROR must be explicitly specified
30+
}

0 commit comments

Comments
 (0)