@@ -20,7 +20,6 @@ use crate::errors::InherentProjectionNormalizationOverflow;
20
20
use crate :: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
21
21
use crate :: infer:: { BoundRegionConversionTime , InferCtxt , InferOk } ;
22
22
use crate :: traits:: error_reporting:: TypeErrCtxtExt as _;
23
- use crate :: traits:: query:: evaluate_obligation:: InferCtxtExt as _;
24
23
use crate :: traits:: select:: ProjectionMatchesProjection ;
25
24
use rustc_data_structures:: sso:: SsoHashSet ;
26
25
use rustc_data_structures:: stack:: ensure_sufficient_stack;
@@ -1791,9 +1790,12 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1791
1790
//
1792
1791
// NOTE: This should be kept in sync with the similar code in
1793
1792
// `rustc_ty_utils::instance::resolve_associated_item()`.
1794
- let node_item =
1795
- specialization_graph:: assoc_def ( selcx. tcx ( ) , impl_data. impl_def_id , obligation. predicate . def_id )
1796
- . map_err ( |ErrorGuaranteed { .. } | ( ) ) ?;
1793
+ let node_item = specialization_graph:: assoc_def (
1794
+ selcx. tcx ( ) ,
1795
+ impl_data. impl_def_id ,
1796
+ obligation. predicate . def_id ,
1797
+ )
1798
+ . map_err ( |ErrorGuaranteed { .. } | ( ) ) ?;
1797
1799
1798
1800
if node_item. is_final ( ) {
1799
1801
// Non-specializable items are always projectable.
@@ -1833,10 +1835,11 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1833
1835
lang_items. fn_trait ( ) ,
1834
1836
lang_items. fn_mut_trait ( ) ,
1835
1837
lang_items. fn_once_trait ( ) ,
1836
- ] . contains ( & Some ( trait_ref. def_id ) )
1838
+ ]
1839
+ . contains ( & Some ( trait_ref. def_id ) )
1837
1840
{
1838
1841
true
1839
- } else if lang_items. discriminant_kind_trait ( ) == Some ( trait_ref. def_id ) {
1842
+ } else if lang_items. discriminant_kind_trait ( ) == Some ( trait_ref. def_id ) {
1840
1843
match self_ty. kind ( ) {
1841
1844
ty:: Bool
1842
1845
| ty:: Char
@@ -1871,9 +1874,16 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1871
1874
| ty:: Error ( _) => false ,
1872
1875
}
1873
1876
} else if lang_items. pointee_trait ( ) == Some ( trait_ref. def_id ) {
1877
+ let metadata_def_id = selcx. tcx ( ) . require_lang_item ( LangItem :: Metadata , None ) ;
1878
+ let self_project = Ty :: new_projection ( selcx. tcx ( ) , metadata_def_id, [ self_ty] ) ;
1879
+
1874
1880
let tail = selcx. tcx ( ) . struct_tail_with_normalize (
1875
1881
self_ty,
1876
1882
|ty| {
1883
+ if ty == self_project {
1884
+ return ty;
1885
+ }
1886
+
1877
1887
// We throw away any obligations we get from this, since we normalize
1878
1888
// and confirm these obligations once again during confirmation
1879
1889
normalize_with_depth (
@@ -1917,23 +1927,10 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1917
1927
| ty:: Infer ( ty:: InferTy :: IntVar ( _) | ty:: InferTy :: FloatVar ( ..) ) => true ,
1918
1928
1919
1929
// We normalize from `Wrapper<Tail>::Metadata` to `Tail::Metadata` if able.
1920
- // Otherwise, type parameters, opaques, and unnormalized projections have
1921
- // unit metadata if they're known (e.g. by the param_env) to be sized.
1922
- ty:: Param ( _) | ty:: Alias ( ..)
1923
- if self_ty != tail || selcx. infcx . predicate_must_hold_modulo_regions (
1924
- & obligation. with (
1925
- selcx. tcx ( ) ,
1926
- ty:: TraitRef :: from_lang_item ( selcx. tcx ( ) , LangItem :: Sized , obligation. cause . span ( ) , [ self_ty] ) ,
1927
- ) ,
1928
- ) =>
1929
- {
1930
- true
1931
- }
1930
+ ty:: Param ( _) | ty:: Alias ( ..) => self_ty != tail,
1932
1931
1933
1932
// FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
1934
- ty:: Param ( _)
1935
- | ty:: Alias ( ..)
1936
- | ty:: Bound ( ..)
1933
+ ty:: Bound ( ..)
1937
1934
| ty:: Placeholder ( ..)
1938
1935
| ty:: Infer ( ..)
1939
1936
| ty:: Error ( _) => {
@@ -2302,23 +2299,14 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
2302
2299
} ;
2303
2300
let metadata_ty = self_ty. ptr_metadata_ty_or_tail ( tcx, normalize) . unwrap_or_else ( |tail| {
2304
2301
if tail == self_ty {
2305
- // This is the "fallback impl" for type parameters, unnormalizable projections
2306
- // and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`.
2307
- // FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't
2308
- // exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`.
2309
- let sized_predicate = ty:: TraitRef :: from_lang_item (
2310
- tcx,
2311
- LangItem :: Sized ,
2302
+ span_bug ! (
2312
2303
obligation. cause. span( ) ,
2313
- [ self_ty ] ,
2304
+ "Pointee projection candidate assembled, but we cannot project further" ,
2314
2305
) ;
2315
- obligations. push ( obligation. with ( tcx, sized_predicate) ) ;
2316
- tcx. types . unit
2317
- } else {
2318
- // We know that `self_ty` has the same metadata as `tail`. This allows us
2319
- // to prove predicates like `Wrapper<Tail>::Metadata == Tail::Metadata`.
2320
- Ty :: new_projection ( tcx, metadata_def_id, [ tail] )
2321
2306
}
2307
+ // We know that `self_ty` has the same metadata as `tail`. This allows us
2308
+ // to prove predicates like `Wrapper<Tail>::Metadata == Tail::Metadata`.
2309
+ Ty :: new_projection ( tcx, metadata_def_id, [ tail] )
2322
2310
} ) ;
2323
2311
( metadata_ty. into ( ) , obligations)
2324
2312
} else {
0 commit comments