Skip to content

Commit

Permalink
address review comments
Browse files Browse the repository at this point in the history
I split the RFC1592 commit out
  • Loading branch information
arielb1 committed Jul 22, 2016
1 parent 23bb1df commit 717e392
Show file tree
Hide file tree
Showing 12 changed files with 74 additions and 85 deletions.
18 changes: 6 additions & 12 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,6 @@ pub enum TypeOrigin {
// FIXME(eddyb) #11161 is the original Expr required?
ExprAssignable(Span),

// Relating trait refs when resolving vtables
RelateTraitRefs(Span),

// Relating self types when resolving vtables
RelateSelfType(Span),

// Relating trait type parameters to those found in impl etc
RelateOutputImplTypes(Span),

Expand All @@ -228,16 +222,17 @@ pub enum TypeOrigin {

// intrinsic has wrong type
IntrinsicType(Span),

// method receiver
MethodReceiver(Span),
}

impl TypeOrigin {
fn as_failure_str(&self) -> &'static str {
match self {
&TypeOrigin::Misc(_) |
&TypeOrigin::RelateSelfType(_) |
&TypeOrigin::RelateOutputImplTypes(_) |
&TypeOrigin::ExprAssignable(_) => "mismatched types",
&TypeOrigin::RelateTraitRefs(_) => "mismatched traits",
&TypeOrigin::MethodCompatCheck(_) => "method not compatible with trait",
&TypeOrigin::MatchExpressionArm(_, _, source) => match source {
hir::MatchSource::IfLetDesugar{..} => "`if let` arms have incompatible types",
Expand All @@ -250,6 +245,7 @@ impl TypeOrigin {
&TypeOrigin::MainFunctionType(_) => "main function has wrong type",
&TypeOrigin::StartFunctionType(_) => "start function has wrong type",
&TypeOrigin::IntrinsicType(_) => "intrinsic has wrong type",
&TypeOrigin::MethodReceiver(_) => "mismatched method receiver",
}
}

Expand All @@ -258,8 +254,6 @@ impl TypeOrigin {
&TypeOrigin::Misc(_) => "types are compatible",
&TypeOrigin::MethodCompatCheck(_) => "method type is compatible with trait",
&TypeOrigin::ExprAssignable(_) => "expression is assignable",
&TypeOrigin::RelateTraitRefs(_) => "traits are compatible",
&TypeOrigin::RelateSelfType(_) => "self type matches impl self type",
&TypeOrigin::RelateOutputImplTypes(_) => {
"trait type parameters matches those specified on the impl"
}
Expand All @@ -271,6 +265,7 @@ impl TypeOrigin {
&TypeOrigin::MainFunctionType(_) => "`main` function has the correct type",
&TypeOrigin::StartFunctionType(_) => "`start` function has the correct type",
&TypeOrigin::IntrinsicType(_) => "intrinsic has the correct type",
&TypeOrigin::MethodReceiver(_) => "method receiver has the correct type",
}
}
}
Expand Down Expand Up @@ -1806,8 +1801,6 @@ impl TypeOrigin {
TypeOrigin::MethodCompatCheck(span) => span,
TypeOrigin::ExprAssignable(span) => span,
TypeOrigin::Misc(span) => span,
TypeOrigin::RelateTraitRefs(span) => span,
TypeOrigin::RelateSelfType(span) => span,
TypeOrigin::RelateOutputImplTypes(span) => span,
TypeOrigin::MatchExpressionArm(match_span, _, _) => match_span,
TypeOrigin::IfExpression(span) => span,
Expand All @@ -1817,6 +1810,7 @@ impl TypeOrigin {
TypeOrigin::MainFunctionType(span) => span,
TypeOrigin::StartFunctionType(span) => span,
TypeOrigin::IntrinsicType(span) => span,
TypeOrigin::MethodReceiver(span) => span,
}
}
}
Expand Down
28 changes: 1 addition & 27 deletions src/librustc_const_eval/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,15 +384,6 @@ pub fn note_const_eval_err<'a, 'tcx>(
diag.span_label(err.span, &message);
}
}
ConstEvalErrDescription::ExpectedFound { error, expected, found } => {
if check_old_school() {
diag.note(&error);
} else {
diag.span_label(err.span, &error);
}
diag.note(&format!("expected `{}`", expected));
diag.note(&format!("found `{}`", found));
}
}

if !primary_span.contains(err.span) {
Expand Down Expand Up @@ -477,26 +468,13 @@ impl From<ConstMathErr> for ErrKind {
#[derive(Clone, Debug)]
pub enum ConstEvalErrDescription<'a> {
Simple(Cow<'a, str>),
ExpectedFound {
error: Cow<'a, str>,
expected: Cow<'a, str>,
found: Cow<'a, str>
}
}

impl<'a> ConstEvalErrDescription<'a> {
/// Return a one-line description of the error, for lints and such
pub fn into_oneline(self) -> Cow<'a, str> {
match self {
ConstEvalErrDescription::Simple(simple) => simple,
ConstEvalErrDescription::ExpectedFound {
error,
expected,
found
} => {
format!("{}: expected `{}`, found `{}`", error, expected, found)
.into_cow()
}
}
}
}
Expand Down Expand Up @@ -554,11 +532,7 @@ impl ConstEvalErr {
the constant evaluator"),

TypeMismatch(ref expected, ref got) => {
ExpectedFound {
error: "mismatched types".into_cow(),
expected: <&str>::into_cow(expected),
found: got.description().into_cow()
}
simple!("expected {}, found {}", expected, got.description())
},
BadType(ref i) => simple!("value of wrong type: {:?}", i),
ErroneousReferencedConstant(_) => simple!("could not evaluate referenced constant"),
Expand Down
9 changes: 8 additions & 1 deletion src/librustc_typeck/check/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}

pub fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
let origin = TypeOrigin::Misc(sp);
self.demand_eqtype_with_origin(TypeOrigin::Misc(sp), expected, actual);
}

pub fn demand_eqtype_with_origin(&self,
origin: TypeOrigin,
expected: Ty<'tcx>,
actual: Ty<'tcx>)
{
match self.eq_types(false, origin, actual, expected) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
Expand Down
44 changes: 31 additions & 13 deletions src/librustc_typeck/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use constrained_type_params::{identify_constrained_type_params, Parameter};
use CrateCtxt;
use hir::def_id::DefId;
use middle::region::{CodeExtent};
use rustc::infer::TypeOrigin;
use rustc::ty::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt};
Expand Down Expand Up @@ -157,7 +158,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
}
}

fn check_trait_or_impl_item(&mut self, item_id: ast::NodeId, span: Span) {
fn check_trait_or_impl_item(&mut self,
item_id: ast::NodeId,
span: Span,
sig_if_method: Option<&hir::MethodSig>) {
let code = self.code.clone();
self.for_id(item_id, span).with_fcx(|fcx, this| {
let free_substs = &fcx.parameter_environment.free_substs;
Expand All @@ -182,7 +186,8 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
let predicates = fcx.instantiate_bounds(span, free_substs, &method.predicates);
this.check_fn_or_method(fcx, span, &method_ty, &predicates,
free_id_outlive, &mut implied_bounds);
this.check_method_receiver(fcx, span, &method,
let sig_if_method = sig_if_method.expect("bad signature for method");
this.check_method_receiver(fcx, sig_if_method, &method,
free_id_outlive, self_ty);
}
ty::TypeTraitItem(assoc_type) => {
Expand Down Expand Up @@ -405,20 +410,15 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {

fn check_method_receiver<'fcx, 'tcx>(&mut self,
fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
span: Span,
method_sig: &hir::MethodSig,
method: &ty::Method<'tcx>,
free_id_outlive: CodeExtent,
self_ty: ty::Ty<'tcx>)
{
// check that the type of the method's receiver matches the
// method's first parameter.

let free_substs = &fcx.parameter_environment.free_substs;
let fty = fcx.instantiate_type_scheme(span, free_substs, &method.fty);
let sig = fcx.tcx.liberate_late_bound_regions(free_id_outlive, &fty.sig);

debug!("check_method_receiver({:?},cat={:?},self_ty={:?},sig={:?})",
method.name, method.explicit_self, self_ty, sig);
debug!("check_method_receiver({:?},cat={:?},self_ty={:?})",
method.name, method.explicit_self, self_ty);

let rcvr_ty = match method.explicit_self {
ty::ExplicitSelfCategory::Static => return,
Expand All @@ -431,13 +431,23 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
}
ty::ExplicitSelfCategory::ByBox => fcx.tcx.mk_box(self_ty)
};

let span = method_sig.decl.inputs[0].pat.span;

let free_substs = &fcx.parameter_environment.free_substs;
let fty = fcx.instantiate_type_scheme(span, free_substs, &method.fty);
let sig = fcx.tcx.liberate_late_bound_regions(free_id_outlive, &fty.sig);

debug!("check_method_receiver: sig={:?}", sig);

let rcvr_ty = fcx.instantiate_type_scheme(span, free_substs, &rcvr_ty);
let rcvr_ty = fcx.tcx.liberate_late_bound_regions(free_id_outlive,
&ty::Binder(rcvr_ty));

debug!("check_method_receiver: receiver ty = {:?}", rcvr_ty);

fcx.demand_eqtype(span, rcvr_ty, sig.inputs[0]);
let origin = TypeOrigin::MethodReceiver(span);
fcx.demand_eqtype_with_origin(origin, rcvr_ty, sig.inputs[0]);
}

fn check_variances_for_type_defn(&self,
Expand Down Expand Up @@ -552,13 +562,21 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {

fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) {
debug!("visit_trait_item: {:?}", trait_item);
self.check_trait_or_impl_item(trait_item.id, trait_item.span);
let method_sig = match trait_item.node {
hir::TraitItem_::MethodTraitItem(ref sig, _) => Some(sig),
_ => None
};
self.check_trait_or_impl_item(trait_item.id, trait_item.span, method_sig);
intravisit::walk_trait_item(self, trait_item)
}

fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) {
debug!("visit_impl_item: {:?}", impl_item);
self.check_trait_or_impl_item(impl_item.id, impl_item.span);
let method_sig = match impl_item.node {
hir::ImplItemKind::Method(ref sig, _) => Some(sig),
_ => None
};
self.check_trait_or_impl_item(impl_item.id, impl_item.span, method_sig);
intravisit::walk_impl_item(self, impl_item)
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/test/compile-fail/const-eval-overflow-4b.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ use std::{u8, u16, u32, u64, usize};
const A_I8_T
: [u32; (i8::MAX as i8 + 1u8) as usize]
//~^ ERROR constant evaluation error [E0080]
//~| mismatched types
//~| expected `i8`
//~| found `u8`
//~| expected i8, found u8
= [0; (i8::MAX as usize) + 1];


Expand Down
16 changes: 8 additions & 8 deletions src/test/compile-fail/discrim-ill-typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn f_i8() {
Ok2,
OhNo = 0_u8,
//~^ ERROR E0080
//~| mismatched types
//~| expected i8, found u8
}

let x = A::Ok;
Expand All @@ -39,7 +39,7 @@ fn f_u8() {
Ok2,
OhNo = 0_i8,
//~^ ERROR E0080
//~| mismatched types
//~| expected u8, found i8
}

let x = A::Ok;
Expand All @@ -52,7 +52,7 @@ fn f_i16() {
Ok2,
OhNo = 0_u16,
//~^ ERROR E0080
//~| mismatched types
//~| expected i16, found u16
}

let x = A::Ok;
Expand All @@ -65,7 +65,7 @@ fn f_u16() {
Ok2,
OhNo = 0_i16,
//~^ ERROR E0080
//~| mismatched types
//~| expected u16, found i16
}

let x = A::Ok;
Expand All @@ -78,7 +78,7 @@ fn f_i32() {
Ok2,
OhNo = 0_u32,
//~^ ERROR E0080
//~| mismatched types
//~| expected i32, found u32
}

let x = A::Ok;
Expand All @@ -91,7 +91,7 @@ fn f_u32() {
Ok2,
OhNo = 0_i32,
//~^ ERROR E0080
//~| mismatched types
//~| expected u32, found i32
}

let x = A::Ok;
Expand All @@ -104,7 +104,7 @@ fn f_i64() {
Ok2,
OhNo = 0_u64,
//~^ ERROR E0080
//~| mismatched types
//~| expected i64, found u64
}

let x = A::Ok;
Expand All @@ -117,7 +117,7 @@ fn f_u64() {
Ok2,
OhNo = 0_i64,
//~^ ERROR E0080
//~| mismatched types
//~| expected u64, found i64
}

let x = A::Ok;
Expand Down
8 changes: 5 additions & 3 deletions src/test/compile-fail/explicit-self-lifetime-mismatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ struct Foo<'a,'b> {
}

impl<'a,'b> Foo<'a,'b> {
fn bar(self: Foo<'b,'a>) {}
//~^ ERROR mismatched types
fn bar(
self
//~^ ERROR mismatched method receiver
//~| expected type `Foo<'a, 'b>`
//~| found type `Foo<'b, 'a>`
//~| lifetime mismatch
//~| ERROR mismatched types
//~| ERROR mismatched method receiver
//~| expected type `Foo<'a, 'b>`
//~| found type `Foo<'b, 'a>`
//~| lifetime mismatch
: Foo<'b,'a>) {}
}

fn main() {}
4 changes: 2 additions & 2 deletions src/test/compile-fail/issue-17740.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ struct Foo<'a> {

impl <'a> Foo<'a>{
fn bar(self: &mut Foo) {
//~^ mismatched types
//~^ mismatched method receiver
//~| expected type `&mut Foo<'a>`
//~| found type `&mut Foo<'_>`
//~| lifetime mismatch
//~| mismatched types
//~| mismatched method receiver
//~| expected type `&mut Foo<'a>`
//~| found type `&mut Foo<'_>`
//~| lifetime mismatch
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-26194.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct S(String);

impl S {
fn f(self: *mut S) -> String { self.0 }
//~^ ERROR mismatched types
//~^ ERROR mismatched method receiver
}

fn main() { S("".to_owned()).f(); }
6 changes: 2 additions & 4 deletions src/test/compile-fail/issue-8761.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@
enum Foo {
A = 1i64,
//~^ ERROR constant evaluation error
//~| expected `isize`
//~| found `i64`
//~| expected isize, found i64
B = 2u8
//~^ ERROR constant evaluation error
//~| expected `isize`
//~| found `u8`
//~| expected isize, found u8
}

fn main() {}
Loading

0 comments on commit 717e392

Please sign in to comment.