Assorted fixed after rebasing
This commit is contained in:
parent
c1df41e776
commit
9734406a5f
@ -162,9 +162,9 @@ impl<'tcx> Substs<'tcx> {
|
||||
|
||||
pub fn with_method_from_subst(self, other: &Substs<'tcx>) -> Substs<'tcx> {
|
||||
let Substs { types, regions } = self;
|
||||
let types = types.with_vec(FnSpace, other.types.get_slice(FnSpace).to_vec());
|
||||
let types = types.with_slice(FnSpace, other.types.get_slice(FnSpace));
|
||||
let regions = regions.map(|r| {
|
||||
r.with_vec(FnSpace, other.regions().get_slice(FnSpace).to_vec())
|
||||
r.with_slice(FnSpace, other.regions().get_slice(FnSpace))
|
||||
});
|
||||
Substs { types: types, regions: regions }
|
||||
}
|
||||
|
@ -1621,7 +1621,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
true
|
||||
},
|
||||
ParamCandidate(..) => false,
|
||||
ErrorCandidate => false // propagate errors
|
||||
},
|
||||
ImplCandidate(other_def) => {
|
||||
// See if we can toss out `victim` based on specialization.
|
||||
|
@ -87,7 +87,7 @@ impl SpecializationGraph {
|
||||
for slot in possible_siblings.iter_mut() {
|
||||
let possible_sibling = *slot;
|
||||
|
||||
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false);
|
||||
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
|
||||
let overlap = traits::overlapping_impls(&infcx, possible_sibling, impl_def_id);
|
||||
|
||||
if let Some(trait_ref) = overlap {
|
||||
|
@ -10,9 +10,10 @@
|
||||
|
||||
use dep_graph::DepNode;
|
||||
use middle::def_id::DefId;
|
||||
use middle::traits;
|
||||
use middle::ty;
|
||||
use middle::ty::fast_reject;
|
||||
use middle::ty::{Ty, TyCtxt};
|
||||
use middle::ty::{Ty, TyCtxt, TraitRef};
|
||||
use std::borrow::{Borrow};
|
||||
use std::cell::{Cell, Ref, RefCell};
|
||||
use syntax::ast::Name;
|
||||
@ -128,6 +129,12 @@ impl<'tcx> TraitDef<'tcx> {
|
||||
debug!("TraitDef::record_impl for {:?}, from {:?}",
|
||||
self, impl_trait_ref);
|
||||
|
||||
// Record the write into the impl set, but only for local
|
||||
// impls: external impls are handled differently.
|
||||
if impl_def_id.is_local() {
|
||||
self.write_trait_impls(tcx);
|
||||
}
|
||||
|
||||
// We don't want to borrow_mut after we already populated all impls,
|
||||
// so check if an impl is present with an immutable borrow first.
|
||||
if let Some(sty) = fast_reject::simplify_type(tcx,
|
||||
|
@ -33,7 +33,8 @@ use trans::glue;
|
||||
use trans::machine;
|
||||
use trans::type_::Type;
|
||||
use trans::type_of::*;
|
||||
use middle::ty::{self, Ty, TyCtxt};
|
||||
use middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use middle::ty::MethodCall;
|
||||
|
||||
use syntax::ast::{self, Name};
|
||||
use syntax::attr;
|
||||
|
@ -872,22 +872,24 @@ fn check_specialization_validity<'tcx, F>(tcx: &ty::ctxt<'tcx>,
|
||||
{
|
||||
let parent_item_opt = traits::get_parent_impl_item(tcx, impl_id, f);
|
||||
if let Some((Defaultness::Final, parent_impl)) = parent_item_opt {
|
||||
span_err!(tcx.sess, impl_item.span, E0520,
|
||||
"item `{}` is provided by an implementation that \
|
||||
specializes another, but the item in the parent \
|
||||
implementations is not marked `default` and so it \
|
||||
cannot be specialized.",
|
||||
impl_item.name);
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess, impl_item.span, E0520,
|
||||
"item `{}` is provided by an implementation that \
|
||||
specializes another, but the item in the parent \
|
||||
implementations is not marked `default` and so it \
|
||||
cannot be specialized.",
|
||||
impl_item.name);
|
||||
|
||||
match tcx.span_of_impl(parent_impl) {
|
||||
Ok(span) => {
|
||||
span_note!(tcx.sess, span, "parent implementation is here:");
|
||||
err.span_note(span, "parent implementation is here:");
|
||||
}
|
||||
Err(cname) => {
|
||||
tcx.sess.note(&format!("parent implementation is in crate `{}`",
|
||||
cname));
|
||||
err.note(&format!("parent implementation is in crate `{}`", cname));
|
||||
}
|
||||
}
|
||||
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,11 +20,10 @@ use syntax::ast;
|
||||
use rustc::dep_graph::DepNode;
|
||||
use rustc_front::hir;
|
||||
use rustc_front::intravisit;
|
||||
use util::nodemap::{DefIdMap, DefIdSet};
|
||||
use util::nodemap::DefIdMap;
|
||||
|
||||
pub fn check(tcx: &TyCtxt) {
|
||||
let mut overlap = OverlapChecker { tcx: tcx,
|
||||
traits_checked: DefIdSet(),
|
||||
default_impls: DefIdMap() };
|
||||
|
||||
// this secondary walk specifically checks for some other cases,
|
||||
@ -35,14 +34,6 @@ pub fn check(tcx: &TyCtxt) {
|
||||
struct OverlapChecker<'cx, 'tcx:'cx> {
|
||||
tcx: &'cx TyCtxt<'tcx>,
|
||||
|
||||
// The set of traits where we have checked for overlap. This is
|
||||
// used to avoid checking the same trait twice.
|
||||
//
|
||||
// NB. It's ok to skip tracking this set because we fully
|
||||
// encapsulate it, and we always create a task
|
||||
// (`CoherenceOverlapCheck`) corresponding to each entry.
|
||||
traits_checked: DefIdSet,
|
||||
|
||||
// maps from a trait def-id to an impl id
|
||||
default_impls: DefIdMap<ast::NodeId>,
|
||||
}
|
||||
@ -120,20 +111,19 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
|
||||
let impl_def_id = self.tcx.map.local_def_id(item.id);
|
||||
let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
|
||||
|
||||
self.check_for_overlapping_impls_of_trait(trait_ref.def_id);
|
||||
|
||||
let prev_default_impl = self.default_impls.insert(trait_ref.def_id, item.id);
|
||||
if let Some(prev_id) = prev_default_impl {
|
||||
span_err!(self.tcx.sess,
|
||||
self.span_of_def_id(impl_def_id), E0519,
|
||||
"redundant default implementations of trait `{}`:",
|
||||
trait_ref);
|
||||
span_note!(self.tcx.sess,
|
||||
self.span_of_def_id(self.tcx.map.local_def_id(prev_id)),
|
||||
"redundant implementation is here:");
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
self.tcx.span_of_impl(impl_def_id).unwrap(), E0519,
|
||||
"redundant default implementations of trait `{}`:",
|
||||
trait_ref);
|
||||
err.span_note(self.tcx.span_of_impl(self.tcx.map.local_def_id(prev_id)).unwrap(),
|
||||
"redundant implementation is here:");
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
hir::ItemImpl(_, _, _, Some(_), ref self_ty, _) => {
|
||||
hir::ItemImpl(_, _, _, Some(_), _, _) => {
|
||||
let impl_def_id = self.tcx.map.local_def_id(item.id);
|
||||
let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
|
||||
let trait_def_id = trait_ref.def_id;
|
||||
@ -162,20 +152,22 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
|
||||
}).unwrap_or(String::new())
|
||||
};
|
||||
|
||||
span_err!(self.tcx.sess, self.span_of_def_id(impl_def_id), E0119,
|
||||
"conflicting implementations of trait `{}`{}:",
|
||||
overlap.on_trait_ref,
|
||||
self_type);
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess, self.tcx.span_of_impl(impl_def_id).unwrap(), E0119,
|
||||
"conflicting implementations of trait `{}`{}:",
|
||||
overlap.on_trait_ref,
|
||||
self_type);
|
||||
|
||||
match self.tcx.span_of_impl(overlap.with_impl) {
|
||||
Ok(span) => {
|
||||
span_note!(self.tcx.sess, span, "conflicting implementation is here:");
|
||||
err.span_note(span, "conflicting implementation is here:");
|
||||
}
|
||||
Err(cname) => {
|
||||
self.tcx.sess.note(&format!("conflicting implementation in crate `{}`",
|
||||
cname));
|
||||
err.note(&format!("conflicting implementation in crate `{}`", cname));
|
||||
}
|
||||
}
|
||||
|
||||
err.emit();
|
||||
}
|
||||
|
||||
// check for overlap with the automatic `impl Trait for Trait`
|
||||
|
@ -69,7 +69,6 @@ use middle::resolve_lifetime;
|
||||
use middle::const_eval::{self, ConstVal};
|
||||
use middle::const_eval::EvalHint::UncheckedExprHint;
|
||||
use middle::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
|
||||
use middle::traits;
|
||||
use middle::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
|
||||
use middle::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
|
||||
use middle::ty::{VariantKind};
|
||||
@ -871,7 +870,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
||||
trait_item.id,
|
||||
hir::Inherited,
|
||||
sig,
|
||||
hir::Defaultness::Default
|
||||
hir::Defaultness::Default,
|
||||
tcx.mk_self_type(),
|
||||
&trait_def.generics,
|
||||
&trait_predicates);
|
||||
|
@ -654,12 +654,12 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eat_contextual_keyword(&mut self, ident: Ident) -> PResult<bool> {
|
||||
pub fn eat_contextual_keyword(&mut self, ident: Ident) -> bool {
|
||||
if self.check_contextual_keyword(ident) {
|
||||
try!(self.bump());
|
||||
Ok(true)
|
||||
self.bump();
|
||||
true
|
||||
} else {
|
||||
Ok(false)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@ -5229,8 +5229,8 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Parse defaultness: DEFAULT or nothing
|
||||
fn parse_defaultness(&mut self) -> PResult<Defaultness> {
|
||||
if try!(self.eat_contextual_keyword(special_idents::DEFAULT)) {
|
||||
fn parse_defaultness(&mut self) -> PResult<'a, Defaultness> {
|
||||
if self.eat_contextual_keyword(special_idents::DEFAULT) {
|
||||
Ok(Defaultness::Default)
|
||||
} else {
|
||||
Ok(Defaultness::Final)
|
||||
|
@ -21,8 +21,8 @@ pub trait Bar {
|
||||
type Output: 'static;
|
||||
}
|
||||
|
||||
impl Foo<i32> for i32 { } //~ ERROR E0119
|
||||
impl Foo<i32> for i32 { }
|
||||
|
||||
impl<A:Iterator> Foo<A::Item> for A { }
|
||||
impl<A:Iterator> Foo<A::Item> for A { } //~ ERROR E0119
|
||||
|
||||
fn main() {}
|
||||
|
@ -15,8 +15,8 @@ use std::marker::PhantomData;
|
||||
|
||||
pub trait Foo<P> {}
|
||||
|
||||
impl <P, T: Foo<P>> Foo<P> for Option<T> {} //~ ERROR E0119
|
||||
impl <P, T: Foo<P>> Foo<P> for Option<T> {}
|
||||
|
||||
impl<T, U> Foo<T> for Option<U> { }
|
||||
impl<T, U> Foo<T> for Option<U> { } //~ ERROR E0119
|
||||
|
||||
fn main() {}
|
||||
|
@ -16,9 +16,9 @@ pub trait Bar {
|
||||
type Output: 'static;
|
||||
}
|
||||
|
||||
impl Foo<i32> for i32 { } //~ ERROR E0119
|
||||
impl Foo<i32> for i32 { }
|
||||
|
||||
impl<A:Bar> Foo<A::Output> for A { }
|
||||
impl<A:Bar> Foo<A::Output> for A { } //~ ERROR E0119
|
||||
|
||||
impl Bar for i32 {
|
||||
type Output = i32;
|
||||
|
Loading…
Reference in New Issue
Block a user