Skip to content

Commit

Permalink
Fix error message spans
Browse files Browse the repository at this point in the history
  • Loading branch information
jroesch authored and Jared Roesch committed Jul 26, 2015
1 parent fbfbdd7 commit ed3fbba
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 77 deletions.
21 changes: 19 additions & 2 deletions src/librustc/ast_map/mod.rs
Expand Up @@ -119,6 +119,7 @@ pub enum Node<'ast> {
NodeStructCtor(&'ast StructDef),

NodeLifetime(&'ast Lifetime),
NodeTyParam(&'ast TyParam)
}

/// Represents an entry and its parent NodeID.
Expand All @@ -142,6 +143,7 @@ enum MapEntry<'ast> {
EntryBlock(NodeId, &'ast Block),
EntryStructCtor(NodeId, &'ast StructDef),
EntryLifetime(NodeId, &'ast Lifetime),
EntryTyParam(NodeId, &'ast TyParam),

/// Roots for node trees.
RootCrate,
Expand Down Expand Up @@ -175,7 +177,8 @@ impl<'ast> MapEntry<'ast> {
NodePat(n) => EntryPat(p, n),
NodeBlock(n) => EntryBlock(p, n),
NodeStructCtor(n) => EntryStructCtor(p, n),
NodeLifetime(n) => EntryLifetime(p, n)
NodeLifetime(n) => EntryLifetime(p, n),
NodeTyParam(n) => EntryTyParam(p, n),
}
}

Expand All @@ -194,6 +197,7 @@ impl<'ast> MapEntry<'ast> {
EntryBlock(id, _) => id,
EntryStructCtor(id, _) => id,
EntryLifetime(id, _) => id,
EntryTyParam(id, _) => id,
_ => return None
})
}
Expand All @@ -213,6 +217,7 @@ impl<'ast> MapEntry<'ast> {
EntryBlock(_, n) => NodeBlock(n),
EntryStructCtor(_, n) => NodeStructCtor(n),
EntryLifetime(_, n) => NodeLifetime(n),
EntryTyParam(_, n) => NodeTyParam(n),
_ => return None
})
}
Expand Down Expand Up @@ -573,6 +578,7 @@ impl<'ast> Map<'ast> {
Some(NodePat(pat)) => pat.span,
Some(NodeBlock(block)) => block.span,
Some(NodeStructCtor(_)) => self.expect_item(self.get_parent(id)).span,
Some(NodeTyParam(ty_param)) => ty_param.span,
_ => return None,
};
Some(sp)
Expand Down Expand Up @@ -815,6 +821,14 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
self.parent_node = parent_node;
}

fn visit_generics(&mut self, generics: &'ast Generics) {
for ty_param in generics.ty_params.iter() {
self.insert(ty_param.id, NodeTyParam(ty_param));
}

visit::walk_generics(self, generics);
}

fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
let parent_node = self.parent_node;
self.parent_node = ti.id;
Expand Down Expand Up @@ -1015,7 +1029,7 @@ impl<'a> NodePrinter for pprust::State<'a> {
NodePat(a) => self.print_pat(&*a),
NodeBlock(a) => self.print_block(&*a),
NodeLifetime(a) => self.print_lifetime(&*a),

NodeTyParam(_) => panic!("cannot print TyParam"),
// these cases do not carry enough information in the
// ast_map to reconstruct their full structure for pretty
// printing.
Expand Down Expand Up @@ -1123,6 +1137,9 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
format!("lifetime {}{}",
pprust::lifetime_to_string(&**l), id_str)
}
Some(NodeTyParam(ref ty_param)) => {
format!("typaram {:?}{}", ty_param, id_str)
}
None => {
format!("unknown node{}", id_str)
}
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/metadata/tydecode.rs
Expand Up @@ -833,6 +833,7 @@ fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
assert_eq!(next(st), '|');
let index = parse_u32(st);
assert_eq!(next(st), '|');
let default_def_id = parse_def_(st, NominalType, conv);
let default = parse_opt(st, |st| parse_ty_(st, conv));
let object_lifetime_default = parse_object_lifetime_default(st, conv);

Expand All @@ -841,6 +842,7 @@ fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
def_id: def_id,
space: space,
index: index,
default_def_id: default_def_id,
default: default,
object_lifetime_default: object_lifetime_default,
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/metadata/tyencode.rs
Expand Up @@ -409,9 +409,9 @@ pub fn enc_region_bounds<'a, 'tcx>(w: &mut Encoder,

pub fn enc_type_param_def<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
v: &ty::TypeParameterDef<'tcx>) {
mywrite!(w, "{}:{}|{}|{}|",
mywrite!(w, "{}:{}|{}|{}|{}|",
token::get_name(v.name), (cx.ds)(v.def_id),
v.space.to_uint(), v.index);
v.space.to_uint(), v.index, (cx.ds)(v.default_def_id));
enc_opt(w, v.default, |w, t| enc_ty(w, cx, t));
enc_object_lifetime_default(w, cx, v.object_lifetime_default);
}
Expand Down
28 changes: 7 additions & 21 deletions src/librustc/middle/infer/mod.rs
Expand Up @@ -40,7 +40,6 @@ use syntax::codemap;
use syntax::codemap::{Span, DUMMY_SP};
use util::nodemap::{FnvHashMap, NodeMap};

use ast_map;
use self::combine::CombineFields;
use self::region_inference::{RegionVarBindings, RegionSnapshot};
use self::error_reporting::ErrorReporting;
Expand Down Expand Up @@ -658,6 +657,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
/// must be attached to the variable when created, if it is created
/// without a default, this will return None.
///
/// This code does not apply to integral or floating point variables,
/// only to use declared defaults.
///
/// See `new_ty_var_with_default` to create a type variable with a default.
/// See `type_variable::Default` for details about what a default entails.
pub fn default(&self, ty: Ty<'tcx>) -> Option<type_variable::Default<'tcx>> {
Expand Down Expand Up @@ -1055,31 +1057,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
substs: &mut Substs<'tcx>,
defs: &[ty::TypeParameterDef<'tcx>]) {

// This doesn't work ...
fn definition_span<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: ast::DefId) -> Span {
let parent = tcx.map.get_parent(def_id.node);
debug!("definition_span def_id={:?} parent={:?} node={:?} parent_node={:?}",
def_id, parent, tcx.map.find(def_id.node), tcx.map.find(parent));
match tcx.map.find(parent) {
None => DUMMY_SP,
Some(ref node) => match *node {
ast_map::NodeItem(ref item) => item.span,
ast_map::NodeForeignItem(ref item) => item.span,
ast_map::NodeTraitItem(ref item) => item.span,
ast_map::NodeImplItem(ref item) => item.span,
_ => DUMMY_SP
}
}
}

let mut vars = Vec::with_capacity(defs.len());

for def in defs.iter() {
let default = def.default.subst_spanned(self.tcx, substs, Some(span)).map(|default| {
let default = def.default.map(|default| {
let definition_span = self.tcx.map.opt_span(def.def_id.node);
type_variable::Default {
ty: default,
ty: default.subst_spanned(self.tcx, substs, Some(span)),
origin_span: span,
definition_span: definition_span(self.tcx, def.def_id)
definition_span: definition_span.unwrap_or(DUMMY_SP)
}
});

Expand Down
9 changes: 4 additions & 5 deletions src/librustc/middle/ty.rs
Expand Up @@ -115,8 +115,6 @@ pub struct Field<'tcx> {
pub mt: TypeAndMut<'tcx>
}



// Enum information
#[derive(Clone)]
pub struct VariantInfo<'tcx> {
Expand Down Expand Up @@ -2282,6 +2280,7 @@ pub struct TypeParameterDef<'tcx> {
pub def_id: ast::DefId,
pub space: subst::ParamSpace,
pub index: u32,
pub default_def_id: DefId, // for use in error reporing about defaults
pub default: Option<Ty<'tcx>>,
pub object_lifetime_default: ObjectLifetimeDefault,
}
Expand Down Expand Up @@ -5084,7 +5083,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
values.found)
},
TyParamDefaultMismatch(ref values) => {
write!(f, "conflicting type parameter defaults {} and {}",
write!(f, "conflicting type parameter defaults `{}` and `{}`",
values.expected.ty,
values.found.ty)
}
Expand Down Expand Up @@ -5453,11 +5452,11 @@ impl<'tcx> ctxt<'tcx> {
expected.ty,
found.ty));
self.sess.span_note(expected.definition_span,
&format!("...a default was defined"));
&format!("a default was defined here..."));
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"));
&format!("a second default was defined here..."));
self.sess.span_note(found.origin_span,
&format!("...that also applies to the same type variable here"));
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/middle/ty_fold.rs
Expand Up @@ -340,6 +340,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> {
space: self.space,
index: self.index,
default: self.default.fold_with(folder),
default_def_id: self.default_def_id,
object_lifetime_default: self.object_lifetime_default.fold_with(folder),
}
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_trans/trans/monomorphize.rs
Expand Up @@ -266,6 +266,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
// Ugh -- but this ensures any new variants won't be forgotten
ast_map::NodeForeignItem(..) |
ast_map::NodeLifetime(..) |
ast_map::NodeTyParam(..) |
ast_map::NodeExpr(..) |
ast_map::NodeStmt(..) |
ast_map::NodeArg(..) |
Expand Down
22 changes: 15 additions & 7 deletions src/librustc_typeck/astconv.rs
Expand Up @@ -55,7 +55,7 @@ use middle::def;
use middle::implicator::object_region_bounds;
use middle::resolve_lifetime as rl;
use middle::privacy::{AllPublic, LastMod};
use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs, ParamSpace};
use middle::traits;
use middle::ty::{self, RegionEscape, Ty, ToPredicate, HasTypeFlags};
use middle::ty_fold;
Expand Down Expand Up @@ -111,7 +111,11 @@ pub trait AstConv<'tcx> {
}

/// What type should we use when a type is omitted?
fn ty_infer(&self, default: Option<ty::TypeParameterDef<'tcx>>, span: Span) -> Ty<'tcx>;
fn ty_infer(&self,
param_and_substs: Option<ty::TypeParameterDef<'tcx>>,
substs: Option<&mut Substs<'tcx>>,
space: Option<ParamSpace>,
span: Span) -> Ty<'tcx>;

/// Projecting an associated type from a (potentially)
/// higher-ranked trait reference is more complicated, because of
Expand Down Expand Up @@ -403,7 +407,11 @@ fn create_substs_for_ast_path<'tcx>(
// they were optional (e.g. paths inside expressions).
let mut type_substs = if param_mode == PathParamMode::Optional &&
types_provided.is_empty() {
ty_param_defs.iter().map(|p| this.ty_infer(Some(p.clone()), span)).collect()
let mut substs = region_substs.clone();
ty_param_defs
.iter()
.map(|p| this.ty_infer(Some(p.clone()), Some(&mut substs), Some(TypeSpace), span))
.collect()
} else {
types_provided
};
Expand Down Expand Up @@ -1661,7 +1669,7 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
// values in a ExprClosure, or as
// the type of local variables. Both of these cases are
// handled specially and will not descend into this routine.
this.ty_infer(None, ast_ty.span)
this.ty_infer(None, None, None, ast_ty.span)
}
};

Expand All @@ -1677,7 +1685,7 @@ pub fn ty_of_arg<'tcx>(this: &AstConv<'tcx>,
{
match a.ty.node {
ast::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
ast::TyInfer => this.ty_infer(None, a.ty.span),
ast::TyInfer => this.ty_infer(None, None, None, a.ty.span),
_ => ast_ty_to_ty(this, rscope, &*a.ty),
}
}
Expand Down Expand Up @@ -1796,7 +1804,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>,

let output_ty = match decl.output {
ast::Return(ref output) if output.node == ast::TyInfer =>
ty::FnConverging(this.ty_infer(None, output.span)),
ty::FnConverging(this.ty_infer(None, None, None, output.span)),
ast::Return(ref output) =>
ty::FnConverging(convert_ty_with_lifetime_elision(this,
implied_output_region,
Expand Down Expand Up @@ -1936,7 +1944,7 @@ pub fn ty_of_closure<'tcx>(
_ if is_infer && expected_ret_ty.is_some() =>
expected_ret_ty.unwrap(),
_ if is_infer =>
ty::FnConverging(this.ty_infer(None, decl.output.span())),
ty::FnConverging(this.ty_infer(None, None, None, decl.output.span())),
ast::Return(ref output) =>
ty::FnConverging(ast_ty_to_ty(this, &rb, &**output)),
ast::DefaultReturn(..) => unreachable!(),
Expand Down

0 comments on commit ed3fbba

Please sign in to comment.