parent
04badd6a97
commit
11aa8756c1
3 changed files with 61 additions and 42 deletions
|
@ -60,7 +60,7 @@ use middle::traits;
|
||||||
use middle::ty::{self, RegionEscape, Ty, ToPredicate, HasTypeFlags};
|
use middle::ty::{self, RegionEscape, Ty, ToPredicate, HasTypeFlags};
|
||||||
use middle::ty_fold;
|
use middle::ty_fold;
|
||||||
use require_c_abi_if_variadic;
|
use require_c_abi_if_variadic;
|
||||||
use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ExplicitRscope,
|
use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
|
||||||
ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope,
|
ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope,
|
||||||
ElisionFailureInfo, ElidedLifetime};
|
ElisionFailureInfo, ElidedLifetime};
|
||||||
use util::common::{ErrorReported, FN_OUTPUT_NAME};
|
use util::common::{ErrorReported, FN_OUTPUT_NAME};
|
||||||
|
@ -1208,40 +1208,33 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||||
(_, def::DefSelfTy(Some(trait_did), Some((impl_id, _)))) => {
|
(_, def::DefSelfTy(Some(trait_did), Some((impl_id, _)))) => {
|
||||||
// `Self` in an impl of a trait - we have a concrete self type and a
|
// `Self` in an impl of a trait - we have a concrete self type and a
|
||||||
// trait reference.
|
// trait reference.
|
||||||
match tcx.map.expect_item(impl_id).node {
|
let trait_ref = tcx.impl_trait_ref(ast_util::local_def(impl_id)).unwrap();
|
||||||
ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) => {
|
let trait_ref = if let Some(free_substs) = this.get_free_substs() {
|
||||||
if this.ensure_super_predicates(span, trait_did).is_err() {
|
trait_ref.subst(tcx, free_substs)
|
||||||
return (tcx.types.err, ty_path_def);
|
} else {
|
||||||
}
|
trait_ref
|
||||||
|
};
|
||||||
|
|
||||||
let trait_segment = &trait_ref.path.segments.last().unwrap();
|
if this.ensure_super_predicates(span, trait_did).is_err() {
|
||||||
let trait_ref = ast_path_to_mono_trait_ref(this,
|
return (tcx.types.err, ty_path_def);
|
||||||
&ExplicitRscope,
|
}
|
||||||
span,
|
|
||||||
PathParamMode::Explicit,
|
|
||||||
trait_did,
|
|
||||||
Some(ty),
|
|
||||||
trait_segment);
|
|
||||||
|
|
||||||
let candidates: Vec<ty::PolyTraitRef> =
|
let candidates: Vec<ty::PolyTraitRef> =
|
||||||
traits::supertraits(tcx, ty::Binder(trait_ref.clone()))
|
traits::supertraits(tcx, ty::Binder(trait_ref))
|
||||||
.filter(|r| this.trait_defines_associated_type_named(r.def_id(),
|
.filter(|r| this.trait_defines_associated_type_named(r.def_id(),
|
||||||
assoc_name))
|
assoc_name))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
match one_bound_for_assoc_type(tcx,
|
match one_bound_for_assoc_type(tcx,
|
||||||
candidates,
|
candidates,
|
||||||
"Self",
|
"Self",
|
||||||
&token::get_name(assoc_name),
|
&token::get_name(assoc_name),
|
||||||
span) {
|
span) {
|
||||||
Ok(bound) => bound,
|
Ok(bound) => bound,
|
||||||
Err(ErrorReported) => return (tcx.types.err, ty_path_def),
|
Err(ErrorReported) => return (tcx.types.err, ty_path_def),
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(&ty::TyParam(_), def::DefSelfTy(Some(trait_did), None)) => {
|
(&ty::TyParam(_), def::DefSelfTy(Some(trait_did), None)) => {
|
||||||
assert_eq!(trait_did.krate, ast::LOCAL_CRATE);
|
assert_eq!(trait_did.krate, ast::LOCAL_CRATE);
|
||||||
match find_bound_for_assoc_item(this,
|
match find_bound_for_assoc_item(this,
|
||||||
trait_did.node,
|
trait_did.node,
|
||||||
|
|
|
@ -836,6 +836,18 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
|
||||||
ty: selfty });
|
ty: selfty });
|
||||||
tcx.predicates.borrow_mut().insert(local_def(it.id),
|
tcx.predicates.borrow_mut().insert(local_def(it.id),
|
||||||
ty_predicates.clone());
|
ty_predicates.clone());
|
||||||
|
if let &Some(ref ast_trait_ref) = opt_trait_ref {
|
||||||
|
tcx.impl_trait_refs.borrow_mut().insert(
|
||||||
|
local_def(it.id),
|
||||||
|
Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
|
||||||
|
&ExplicitRscope,
|
||||||
|
ast_trait_ref,
|
||||||
|
Some(selfty)))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
tcx.impl_trait_refs.borrow_mut().insert(local_def(it.id), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// If there is a trait reference, treat the methods as always public.
|
// If there is a trait reference, treat the methods as always public.
|
||||||
// This is to work around some incorrect behavior in privacy checking:
|
// This is to work around some incorrect behavior in privacy checking:
|
||||||
|
@ -935,18 +947,6 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let &Some(ref ast_trait_ref) = opt_trait_ref {
|
|
||||||
tcx.impl_trait_refs.borrow_mut().insert(
|
|
||||||
local_def(it.id),
|
|
||||||
Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
|
|
||||||
&ExplicitRscope,
|
|
||||||
ast_trait_ref,
|
|
||||||
Some(selfty)))
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
tcx.impl_trait_refs.borrow_mut().insert(local_def(it.id), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
enforce_impl_params_are_constrained(tcx,
|
enforce_impl_params_are_constrained(tcx,
|
||||||
generics,
|
generics,
|
||||||
local_def(it.id),
|
local_def(it.id),
|
||||||
|
|
26
src/test/run-pass/issue-27281.rs
Normal file
26
src/test/run-pass/issue-27281.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// 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 Trait<'a> {
|
||||||
|
type T;
|
||||||
|
type U;
|
||||||
|
fn foo(&self, s: &'a ()) -> &'a ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Trait<'a> for () {
|
||||||
|
type T = &'a ();
|
||||||
|
type U = Self::T;
|
||||||
|
|
||||||
|
fn foo(&self, s: &'a ()) -> &'a () {
|
||||||
|
let t: Self::T = s; t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue