Skip to content

Commit 08660af

Browse files
Remove unreachable branches in traits::project
1 parent 42051ce commit 08660af

File tree

1 file changed

+72
-116
lines changed

1 file changed

+72
-116
lines changed

src/librustc/traits/project.rs

+72-116
Original file line numberDiff line numberDiff line change
@@ -900,96 +900,50 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
900900
// In either case, we handle this by not adding a
901901
// candidate for an impl if it contains a `default`
902902
// type.
903-
let opt_node_item = assoc_ty_def(selcx,
904-
impl_data.impl_def_id,
905-
obligation.predicate.item_name);
906-
let new_candidate = if let Some(node_item) = opt_node_item {
907-
let is_default = if node_item.node.is_from_trait() {
908-
// If true, the impl inherited a `type Foo = Bar`
909-
// given in the trait, which is implicitly default.
910-
// Otherwise, the impl did not specify `type` and
911-
// neither did the trait:
912-
//
913-
// ```rust
914-
// trait Foo { type T; }
915-
// impl Foo for Bar { }
916-
// ```
917-
//
918-
// This is an error, but it will be
919-
// reported in `check_impl_items_against_trait`.
920-
// We accept it here but will flag it as
921-
// an error when we confirm the candidate
922-
// (which will ultimately lead to `normalize_to_error`
923-
// being invoked).
924-
node_item.item.defaultness.has_value()
925-
} else {
926-
node_item.item.defaultness.is_default() ||
927-
selcx.tcx().impl_is_default(node_item.node.def_id())
928-
};
929-
930-
// Only reveal a specializable default if we're past type-checking
931-
// and the obligations is monomorphic, otherwise passes such as
932-
// transmute checking and polymorphic MIR optimizations could
933-
// get a result which isn't correct for all monomorphizations.
934-
if !is_default {
903+
let node_item = assoc_ty_def(selcx,
904+
impl_data.impl_def_id,
905+
obligation.predicate.item_name);
906+
907+
let is_default = if node_item.node.is_from_trait() {
908+
// If true, the impl inherited a `type Foo = Bar`
909+
// given in the trait, which is implicitly default.
910+
// Otherwise, the impl did not specify `type` and
911+
// neither did the trait:
912+
//
913+
// ```rust
914+
// trait Foo { type T; }
915+
// impl Foo for Bar { }
916+
// ```
917+
//
918+
// This is an error, but it will be
919+
// reported in `check_impl_items_against_trait`.
920+
// We accept it here but will flag it as
921+
// an error when we confirm the candidate
922+
// (which will ultimately lead to `normalize_to_error`
923+
// being invoked).
924+
node_item.item.defaultness.has_value()
925+
} else {
926+
node_item.item.defaultness.is_default() ||
927+
selcx.tcx().impl_is_default(node_item.node.def_id())
928+
};
929+
930+
// Only reveal a specializable default if we're past type-checking
931+
// and the obligations is monomorphic, otherwise passes such as
932+
// transmute checking and polymorphic MIR optimizations could
933+
// get a result which isn't correct for all monomorphizations.
934+
let new_candidate = if !is_default {
935+
Some(ProjectionTyCandidate::Select)
936+
} else if selcx.projection_mode() == Reveal::All {
937+
assert!(!poly_trait_ref.needs_infer());
938+
if !poly_trait_ref.needs_subst() {
935939
Some(ProjectionTyCandidate::Select)
936-
} else if selcx.projection_mode() == Reveal::All {
937-
assert!(!poly_trait_ref.needs_infer());
938-
if !poly_trait_ref.needs_subst() {
939-
Some(ProjectionTyCandidate::Select)
940-
} else {
941-
None
942-
}
943940
} else {
944941
None
945942
}
946943
} else {
947-
// This is saying that neither the trait nor
948-
// the impl contain a definition for this
949-
// associated type. Normally this situation
950-
// could only arise through a compiler bug --
951-
// if the user wrote a bad item name, it
952-
// should have failed in astconv. **However**,
953-
// at coherence-checking time, we only look at
954-
// the topmost impl (we don't even consider
955-
// the trait itself) for the definition -- and
956-
// so in that case it may be that the trait
957-
// *DOES* have a declaration, but we don't see
958-
// it, and we end up in this branch.
959-
//
960-
// This is kind of tricky to handle actually.
961-
// For now, we just unconditionally ICE,
962-
// because otherwise, examples like the
963-
// following will succeed:
964-
//
965-
// ```
966-
// trait Assoc {
967-
// type Output;
968-
// }
969-
//
970-
// impl<T> Assoc for T {
971-
// default type Output = bool;
972-
// }
973-
//
974-
// impl Assoc for u8 {}
975-
// impl Assoc for u16 {}
976-
//
977-
// trait Foo {}
978-
// impl Foo for <u8 as Assoc>::Output {}
979-
// impl Foo for <u16 as Assoc>::Output {}
980-
// return None;
981-
// }
982-
// ```
983-
//
984-
// The essential problem here is that the
985-
// projection fails, leaving two unnormalized
986-
// types, which appear not to unify -- so the
987-
// overlap check succeeds, when it should
988-
// fail.
989-
span_bug!(obligation.cause.span,
990-
"Tried to project an inherited associated type during \
991-
coherence checking, which is currently not supported.");
944+
None
992945
};
946+
993947
candidate_set.vec.extend(new_candidate);
994948
}
995949
super::VtableParam(..) => {
@@ -1274,35 +1228,25 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
12741228
let VtableImplData { substs, nested, impl_def_id } = impl_vtable;
12751229

12761230
let tcx = selcx.tcx();
1277-
let trait_ref = obligation.predicate.trait_ref;
12781231
let assoc_ty = assoc_ty_def(selcx, impl_def_id, obligation.predicate.item_name);
12791232

1280-
match assoc_ty {
1281-
Some(node_item) => {
1282-
let ty = if !node_item.item.defaultness.has_value() {
1283-
// This means that the impl is missing a definition for the
1284-
// associated type. This error will be reported by the type
1285-
// checker method `check_impl_items_against_trait`, so here we
1286-
// just return TyError.
1287-
debug!("confirm_impl_candidate: no associated type {:?} for {:?}",
1288-
node_item.item.name,
1289-
obligation.predicate.trait_ref);
1290-
tcx.types.err
1291-
} else {
1292-
tcx.type_of(node_item.item.def_id)
1293-
};
1294-
let substs = translate_substs(selcx.infcx(), impl_def_id, substs, node_item.node);
1295-
Progress {
1296-
ty: ty.subst(tcx, substs),
1297-
obligations: nested,
1298-
cacheable: true
1299-
}
1300-
}
1301-
None => {
1302-
span_bug!(obligation.cause.span,
1303-
"No associated type for {:?}",
1304-
trait_ref);
1305-
}
1233+
let ty = if !assoc_ty.item.defaultness.has_value() {
1234+
// This means that the impl is missing a definition for the
1235+
// associated type. This error will be reported by the type
1236+
// checker method `check_impl_items_against_trait`, so here we
1237+
// just return TyError.
1238+
debug!("confirm_impl_candidate: no associated type {:?} for {:?}",
1239+
assoc_ty.item.name,
1240+
obligation.predicate.trait_ref);
1241+
tcx.types.err
1242+
} else {
1243+
tcx.type_of(assoc_ty.item.def_id)
1244+
};
1245+
let substs = translate_substs(selcx.infcx(), impl_def_id, substs, assoc_ty.node);
1246+
Progress {
1247+
ty: ty.subst(tcx, substs),
1248+
obligations: nested,
1249+
cacheable: true
13061250
}
13071251
}
13081252

@@ -1315,7 +1259,7 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>(
13151259
selcx: &SelectionContext<'cx, 'gcx, 'tcx>,
13161260
impl_def_id: DefId,
13171261
assoc_ty_name: ast::Name)
1318-
-> Option<specialization_graph::NodeItem<ty::AssociatedItem>>
1262+
-> specialization_graph::NodeItem<ty::AssociatedItem>
13191263
{
13201264
let tcx = selcx.tcx();
13211265
let trait_def_id = tcx.impl_trait_ref(impl_def_id).unwrap().def_id;
@@ -1330,17 +1274,29 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>(
13301274
let impl_node = specialization_graph::Node::Impl(impl_def_id);
13311275
for item in impl_node.items(tcx) {
13321276
if item.kind == ty::AssociatedKind::Type && item.name == assoc_ty_name {
1333-
return Some(specialization_graph::NodeItem {
1277+
return specialization_graph::NodeItem {
13341278
node: specialization_graph::Node::Impl(impl_def_id),
13351279
item: item,
1336-
});
1280+
};
13371281
}
13381282
}
13391283

1340-
trait_def
1284+
if let Some(assoc_item) = trait_def
13411285
.ancestors(tcx, impl_def_id)
13421286
.defs(tcx, assoc_ty_name, ty::AssociatedKind::Type)
1343-
.next()
1287+
.next() {
1288+
assoc_item
1289+
} else {
1290+
// This is saying that neither the trait nor
1291+
// the impl contain a definition for this
1292+
// associated type. Normally this situation
1293+
// could only arise through a compiler bug --
1294+
// if the user wrote a bad item name, it
1295+
// should have failed in astconv.
1296+
bug!("No associated type `{}` for {}",
1297+
assoc_ty_name,
1298+
tcx.item_path_str(impl_def_id))
1299+
}
13441300
}
13451301

13461302
// # Cache

0 commit comments

Comments
 (0)