diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 7d50e6f6917cc..fb11aaed61958 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -56,6 +56,7 @@ #![feature(slice_splits)] #![feature(slice_patterns)] #![feature(slice_position_elem)] +#![feature(slice_concat_ext)] #![feature(staged_api)] #![feature(str_char)] #![feature(str_match_indices)] diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index d10dd7073532b..f63154af72426 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -1061,11 +1061,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { for def in defs.iter() { let default = def.default.map(|default| { - let definition_span = self.tcx.map.opt_span(def.def_id.node); type_variable::Default { ty: default.subst_spanned(self.tcx, substs, Some(span)), origin_span: span, - definition_span: definition_span.unwrap_or(DUMMY_SP) + def_id: def.default_def_id } }); diff --git a/src/librustc/middle/infer/type_variable.rs b/src/librustc/middle/infer/type_variable.rs index 8707306a149c7..3684651f85be6 100644 --- a/src/librustc/middle/infer/type_variable.rs +++ b/src/librustc/middle/infer/type_variable.rs @@ -12,6 +12,7 @@ pub use self::RelationDir::*; use self::TypeVariableValue::*; use self::UndoEntry::*; use middle::ty::{self, Ty}; +use syntax::ast::DefId; use syntax::codemap::Span; use std::cmp::min; @@ -45,7 +46,7 @@ pub struct Default<'tcx> { /// The span where the default was incurred pub origin_span: Span, /// The definition that the default originates from - pub definition_span: Span + pub def_id: DefId } pub struct Snapshot { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index a4f714b3bf9c7..3bda1730e63b8 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -79,6 +79,7 @@ use std::ops; use std::rc::Rc; use std::vec::IntoIter; use collections::enum_set::{self, EnumSet, CLike}; +use collections::slice::SliceConcatExt; use std::collections::{HashMap, HashSet}; use syntax::abi; use syntax::ast::{CrateNum, DefId, ItemImpl, ItemTrait, LOCAL_CRATE}; @@ -5448,17 +5449,47 @@ impl<'tcx> ctxt<'tcx> { let expected = values.expected; let found = values.found; self.sess.span_note(sp, - &format!("conflicting type parameter defaults {} and {}", - expected.ty, - found.ty)); - self.sess.span_note(expected.definition_span, - &format!("a default was defined here...")); + &format!("conflicting type parameter defaults `{}` and `{}`", + expected.ty, + found.ty)); + + match (expected.def_id.krate == ast::LOCAL_CRATE, self.map.opt_span(expected.def_id.node)) { + (true, Some(span)) => { + self.sess.span_note(span, + &format!("a default was defined here...")); + } + (_, _) => { + let elems = csearch::get_item_path(self, expected.def_id) + .into_iter() + .map(|p| p.to_string()) + .collect::>(); + self.sess.note( + &format!("a default is defined on `{}`", + elems.join("::"))); + } + } + self.sess.span_note(expected.origin_span, - &format!("...that was applied to an unconstrained type variable here")); - self.sess.span_note(found.definition_span, - &format!("a second default was defined here...")); + &format!("...that was applied to an unconstrained type variable here")); + + match (found.def_id.krate == ast::LOCAL_CRATE, self.map.opt_span(found.def_id.node)) { + (true, Some(span)) => { + self.sess.span_note(span, + &format!("a second default was defined here...")); + } + (_, _) => { + let elems = csearch::get_item_path(self, found.def_id) + .into_iter() + .map(|p| p.to_string()) + .collect::>(); + + self.sess.note( + &format!("a second default is defined on `{}`", elems.join(" "))); + } + } + self.sess.span_note(found.origin_span, - &format!("...that also applies to the same type variable here")); + &format!("...that also applies to the same type variable here")); } _ => {} } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 76886fc1275bd..fd4cf6f28df91 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1146,14 +1146,10 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { span: Span) -> Ty<'tcx> { // Grab the default doing subsitution let default = ty_param_def.and_then(|def| { - let definition_span = self.tcx() - .map - .opt_span(def.def_id.node); - def.default.map(|ty| type_variable::Default { ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)), origin_span: span, - definition_span: definition_span.unwrap_or(codemap::DUMMY_SP) + def_id: def.default_def_id }) }); @@ -1850,7 +1846,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or(type_variable::Default { ty: self.infcx().next_ty_var(), origin_span: codemap::DUMMY_SP, - definition_span: codemap::DUMMY_SP + def_id: local_def(0) // what do I put here? }); self.infcx().report_conflicting_default_types( diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 6bff90825f328..d31a29ecc0e2c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1647,12 +1647,14 @@ fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // the node id for the Self type parameter. let param_id = trait_id; + let parent = ccx.tcx.map.get_parent(param_id); + let def = ty::TypeParameterDef { space: SelfSpace, index: 0, name: special_idents::type_self.name, def_id: local_def(param_id), - default_def_id: local_def(param_id), + default_def_id: local_def(parent), default: None, object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault, }; @@ -1921,13 +1923,15 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, compute_object_lifetime_default(ccx, param.id, ¶m.bounds, &ast_generics.where_clause); + let parent = tcx.map.get_parent(param.id); + let def = ty::TypeParameterDef { space: space, index: index, name: param.ident.name, def_id: local_def(param.id), // what do I return? should this be an option as well - default_def_id: local_def(param.default.as_ref().map(|d| d.id).unwrap_or(param.id)), + default_def_id: local_def(parent), default: default, object_lifetime_default: object_lifetime_default, };