Skip to content

Commit 9a196aa

Browse files
committed
Auto merge of #27283 - arielb1:free-self-2, r=eddyb
Fixes #27281 r? @eddyb
2 parents 7276d8b + 11aa875 commit 9a196aa

File tree

3 files changed

+63
-44
lines changed

3 files changed

+63
-44
lines changed

src/librustc_typeck/astconv.rs

+25-32
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use middle::traits;
6060
use middle::ty::{self, RegionEscape, Ty, ToPredicate, HasTypeFlags};
6161
use middle::ty_fold;
6262
use require_c_abi_if_variadic;
63-
use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ExplicitRscope,
63+
use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
6464
ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope,
6565
ElisionFailureInfo, ElidedLifetime};
6666
use util::common::{ErrorReported, FN_OUTPUT_NAME};
@@ -1208,40 +1208,33 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
12081208
(_, def::DefSelfTy(Some(trait_did), Some((impl_id, _)))) => {
12091209
// `Self` in an impl of a trait - we have a concrete self type and a
12101210
// trait reference.
1211-
match tcx.map.expect_item(impl_id).node {
1212-
ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) => {
1213-
if this.ensure_super_predicates(span, trait_did).is_err() {
1214-
return (tcx.types.err, ty_path_def);
1215-
}
1211+
let trait_ref = tcx.impl_trait_ref(ast_util::local_def(impl_id)).unwrap();
1212+
let trait_ref = if let Some(free_substs) = this.get_free_substs() {
1213+
trait_ref.subst(tcx, free_substs)
1214+
} else {
1215+
trait_ref
1216+
};
12161217

1217-
let trait_segment = &trait_ref.path.segments.last().unwrap();
1218-
let trait_ref = ast_path_to_mono_trait_ref(this,
1219-
&ExplicitRscope,
1220-
span,
1221-
PathParamMode::Explicit,
1222-
trait_did,
1223-
Some(ty),
1224-
trait_segment);
1225-
1226-
let candidates: Vec<ty::PolyTraitRef> =
1227-
traits::supertraits(tcx, ty::Binder(trait_ref.clone()))
1228-
.filter(|r| this.trait_defines_associated_type_named(r.def_id(),
1229-
assoc_name))
1230-
.collect();
1231-
1232-
match one_bound_for_assoc_type(tcx,
1233-
candidates,
1234-
"Self",
1235-
&token::get_name(assoc_name),
1236-
span) {
1237-
Ok(bound) => bound,
1238-
Err(ErrorReported) => return (tcx.types.err, ty_path_def),
1239-
}
1240-
}
1241-
_ => unreachable!()
1218+
if this.ensure_super_predicates(span, trait_did).is_err() {
1219+
return (tcx.types.err, ty_path_def);
1220+
}
1221+
1222+
let candidates: Vec<ty::PolyTraitRef> =
1223+
traits::supertraits(tcx, ty::Binder(trait_ref))
1224+
.filter(|r| this.trait_defines_associated_type_named(r.def_id(),
1225+
assoc_name))
1226+
.collect();
1227+
1228+
match one_bound_for_assoc_type(tcx,
1229+
candidates,
1230+
"Self",
1231+
&token::get_name(assoc_name),
1232+
span) {
1233+
Ok(bound) => bound,
1234+
Err(ErrorReported) => return (tcx.types.err, ty_path_def),
12421235
}
12431236
}
1244-
(&ty::TyParam(_), def::DefSelfTy(Some(trait_did), None)) => {
1237+
(&ty::TyParam(_), def::DefSelfTy(Some(trait_did), None)) => {
12451238
assert_eq!(trait_did.krate, ast::LOCAL_CRATE);
12461239
match find_bound_for_assoc_item(this,
12471240
trait_did.node,

src/librustc_typeck/collect.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,18 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
836836
ty: selfty });
837837
tcx.predicates.borrow_mut().insert(local_def(it.id),
838838
ty_predicates.clone());
839+
if let &Some(ref ast_trait_ref) = opt_trait_ref {
840+
tcx.impl_trait_refs.borrow_mut().insert(
841+
local_def(it.id),
842+
Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
843+
&ExplicitRscope,
844+
ast_trait_ref,
845+
Some(selfty)))
846+
);
847+
} else {
848+
tcx.impl_trait_refs.borrow_mut().insert(local_def(it.id), None);
849+
}
850+
839851

840852
// If there is a trait reference, treat the methods as always public.
841853
// This is to work around some incorrect behavior in privacy checking:
@@ -935,18 +947,6 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
935947
}
936948
}
937949

938-
if let &Some(ref ast_trait_ref) = opt_trait_ref {
939-
tcx.impl_trait_refs.borrow_mut().insert(
940-
local_def(it.id),
941-
Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
942-
&ExplicitRscope,
943-
ast_trait_ref,
944-
Some(selfty)))
945-
);
946-
} else {
947-
tcx.impl_trait_refs.borrow_mut().insert(local_def(it.id), None);
948-
}
949-
950950
enforce_impl_params_are_constrained(tcx,
951951
generics,
952952
local_def(it.id),

src/test/run-pass/issue-27281.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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 Trait<'a> {
12+
type T;
13+
type U;
14+
fn foo(&self, s: &'a ()) -> &'a ();
15+
}
16+
17+
impl<'a> Trait<'a> for () {
18+
type T = &'a ();
19+
type U = Self::T;
20+
21+
fn foo(&self, s: &'a ()) -> &'a () {
22+
let t: Self::T = s; t
23+
}
24+
}
25+
26+
fn main() {}

0 commit comments

Comments
 (0)