@@ -93,7 +93,7 @@ pub enum Reveal {
9393 /// }
9494 NotSpecializable ,
9595
96- /// At trans time, all projections will succeed.
96+ /// At trans time, all monomorphic projections will succeed.
9797 All ,
9898}
9999
@@ -878,7 +878,7 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
878878
879879 candidate_set. vec . push ( ProjectionTyCandidate :: Select ) ;
880880 }
881- super :: VtableImpl ( ref impl_data) if selcx . projection_mode ( ) != Reveal :: All => {
881+ super :: VtableImpl ( ref impl_data) => {
882882 // We have to be careful when projecting out of an
883883 // impl because of specialization. If we are not in
884884 // trans (i.e., projection mode is not "any"), and the
@@ -902,37 +902,43 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
902902 impl_data. impl_def_id ,
903903 obligation. predicate . item_name ) ;
904904 let new_candidate = if let Some ( node_item) = opt_node_item {
905- if node_item. node . is_from_trait ( ) {
906- if node_item. item . ty . is_some ( ) {
907- // The impl inherited a `type Foo =
908- // Bar` given in the trait, which is
909- // implicitly default. No candidate.
910- None
911- } else {
912- // The impl did not specify `type` and neither
913- // did the trait:
914- //
915- // ```rust
916- // trait Foo { type T; }
917- // impl Foo for Bar { }
918- // ```
919- //
920- // This is an error, but it will be
921- // reported in `check_impl_items_against_trait`.
922- // We accept it here but will flag it as
923- // an error when we confirm the candidate
924- // (which will ultimately lead to `normalize_to_error`
925- // being invoked).
905+ let is_default = if node_item. node . is_from_trait ( ) {
906+ // If true, the impl inherited a `type Foo = Bar`
907+ // given in the trait, which is implicitly default.
908+ // Otherwise, the impl did not specify `type` and
909+ // neither did the trait:
910+ //
911+ // ```rust
912+ // trait Foo { type T; }
913+ // impl Foo for Bar { }
914+ // ```
915+ //
916+ // This is an error, but it will be
917+ // reported in `check_impl_items_against_trait`.
918+ // We accept it here but will flag it as
919+ // an error when we confirm the candidate
920+ // (which will ultimately lead to `normalize_to_error`
921+ // being invoked).
922+ node_item. item . ty . is_some ( )
923+ } else {
924+ node_item. item . defaultness . is_default ( )
925+ } ;
926+
927+ // Only reveal a specializable default if we're past type-checking
928+ // and the obligations is monomorphic, otherwise passes such as
929+ // transmute checking and polymorphic MIR optimizations could
930+ // get a result which isn't correct for all monomorphizations.
931+ if !is_default {
932+ Some ( ProjectionTyCandidate :: Select )
933+ } else if selcx. projection_mode ( ) == Reveal :: All {
934+ assert ! ( !poly_trait_ref. needs_infer( ) ) ;
935+ if !poly_trait_ref. needs_subst ( ) {
926936 Some ( ProjectionTyCandidate :: Select )
937+ } else {
938+ None
927939 }
928- } else if node_item. item . defaultness . is_default ( ) {
929- // The impl specified `default type Foo =
930- // Bar`. No candidate.
931- None
932940 } else {
933- // The impl specified `type Foo = Bar`
934- // with no default. Add a candidate.
935- Some ( ProjectionTyCandidate :: Select )
941+ None
936942 }
937943 } else {
938944 // This is saying that neither the trait nor
@@ -982,11 +988,6 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
982988 } ;
983989 candidate_set. vec . extend ( new_candidate) ;
984990 }
985- super :: VtableImpl ( _) => {
986- // In trans mode, we can just project out of impls, no prob.
987- assert ! ( selcx. projection_mode( ) == Reveal :: All ) ;
988- candidate_set. vec . push ( ProjectionTyCandidate :: Select ) ;
989- }
990991 super :: VtableParam ( ..) => {
991992 // This case tell us nothing about the value of an
992993 // associated type. Consider:
0 commit comments