Skip to content

Add note to type mismatch errors related to specialization. #33599

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
predicate,
error.err);
self.note_obligation_cause(&mut err, obligation);
self.tcx.note_and_explain_type_err(&mut err, &error.err, obligation.cause.span);
err.emit();
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/librustc/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ pub enum ProjectionMode {
/// }
///
/// fn main() {
/// let <() as Assoc>::Output = true;
/// let x: <() as Assoc>::Output = true;
/// }
/// ```
AnyFinal,

/// At trans time, all projections will succeed.
Expand Down Expand Up @@ -697,7 +698,7 @@ fn project_type<'cx, 'gcx, 'tcx>(
return None;
}
} else {
// Normally this situation could only arise througha
// Normally this situation could only arise through a
// compiler bug, but at coherence-checking time we only look
// at the topmost impl (we don't even consider the trait
// itself) for the definition -- so we can fail to find a
Expand All @@ -721,8 +722,6 @@ fn project_type<'cx, 'gcx, 'tcx>(
// trait Foo {}
// impl Foo for <u8 as Assoc>::Output {}
// impl Foo for <u16 as Assoc>::Output {}
// return None;
// }
// ```
//
// The essential problem here is that the projection fails,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,

fulfill_implication(infcx, source_trait_ref, target_impl).unwrap_or_else(|_| {
bug!("When translating substitutions for specialization, the expected \
specializaiton failed to hold")
specialization failed to hold")
})
}
specialization_graph::Node::Trait(..) => source_trait_ref.substs,
Expand Down
26 changes: 24 additions & 2 deletions src/librustc/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use hir::def_id::DefId;
use ty::subst;
use infer::type_variable;
use ty::{self, BoundRegion, Region, Ty, TyCtxt};
use ty::{self, BoundRegion, Region, Ty, TyCtxt, TypeFoldable};

use std::fmt;
use syntax::abi;
Expand Down Expand Up @@ -58,7 +58,8 @@ pub enum TypeError<'tcx> {
ConvergenceMismatch(ExpectedFound<bool>),
ProjectionNameMismatched(ExpectedFound<Name>),
ProjectionBoundsLength(ExpectedFound<usize>),
TyParamDefaultMismatch(ExpectedFound<type_variable::Default<'tcx>>)
TyParamDefaultMismatch(ExpectedFound<type_variable::Default<'tcx>>),
UnnormalizedProjectionMismatch(ExpectedFound<Ty<'tcx>>),
}

#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
Expand Down Expand Up @@ -206,6 +207,10 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
values.expected.ty,
values.found.ty)
}
UnnormalizedProjectionMismatch(values) => ty::tls::with(|tcx| {
report_maybe_different(f, values.expected.sort_string(tcx),
values.found.sort_string(tcx))
}),
}
}
}
Expand Down Expand Up @@ -337,6 +342,23 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
db.span_note(found.origin_span,
"...that also applies to the same type variable here");
}
UnnormalizedProjectionMismatch(values) => {
let (proj, _) = if let &ty::TyProjection(_) = &values.found.sty {
(values.found, values.expected)
} else {
(values.expected, values.found)
};

// a type projection failure with no unsubstituted type parameters
// stems from specialization intentionally rejecting type projections for default
// implementations.
if proj.needs_subst() || proj.needs_infer() {
return;
}

db.note("associated types marked as `default` cannot be projected \
as a specific type.");
}
_ => {}
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,11 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
Ok(tcx.mk_projection(projection_ty.trait_ref, projection_ty.item_name))
}

(&ty::TyProjection(_), _) | (_, &ty::TyProjection(_)) =>
{
Err(TypeError::UnnormalizedProjectionMismatch(expected_found(relation, &a, &b)))
}

_ =>
{
Err(TypeError::Sorts(expected_found(relation, &a, &b)))
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,9 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
TyParamDefaultMismatch(ref x) => {
return tcx.lift(x).map(TyParamDefaultMismatch)
}
UnnormalizedProjectionMismatch(ref x) => {
return tcx.lift(x).map(UnnormalizedProjectionMismatch)
}
})
}
}
Expand Down