@@ -42,115 +42,96 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
4242 obligation : & TraitObligation < ' tcx > ,
4343 candidate : SelectionCandidate < ' tcx > ,
4444 ) -> Result < Selection < ' tcx > , SelectionError < ' tcx > > {
45- let mut obligation = obligation;
46- let new_obligation;
47-
48- // HACK(const_trait_impl): the surrounding environment is remapped to a non-const context
49- // because nested obligations might be actually `~const` then (incorrectly) requiring
50- // const impls. for example:
51- // ```
52- // pub trait Super {}
53- // pub trait Sub: Super {}
54- //
55- // impl<A> const Super for &A where A: ~const Super {}
56- // impl<A> const Sub for &A where A: ~const Sub {}
57- // ```
58- //
59- // The procedure to check the code above without the remapping code is as follows:
60- // ```
61- // CheckWf(impl const Sub for &A where A: ~const Sub) // <- const env
62- // CheckPredicate(&A: Super)
63- // CheckPredicate(A: ~const Super) // <- still const env, failure
64- // ```
65- if obligation. param_env . is_const ( ) && !obligation. predicate . is_const_if_const ( ) {
66- new_obligation = TraitObligation {
67- cause : obligation. cause . clone ( ) ,
68- param_env : obligation. param_env . without_const ( ) ,
69- ..* obligation
70- } ;
71- obligation = & new_obligation;
72- }
73-
74- match candidate {
45+ let mut impl_src = match candidate {
7546 BuiltinCandidate { has_nested } => {
7647 let data = self . confirm_builtin_candidate ( obligation, has_nested) ;
77- Ok ( ImplSource :: Builtin ( data) )
48+ ImplSource :: Builtin ( data)
7849 }
7950
8051 ParamCandidate ( param) => {
8152 let obligations =
8253 self . confirm_param_candidate ( obligation, param. map_bound ( |t| t. trait_ref ) ) ;
83- Ok ( ImplSource :: Param ( obligations, param. skip_binder ( ) . constness ) )
54+ ImplSource :: Param ( obligations, param. skip_binder ( ) . constness )
8455 }
8556
8657 ImplCandidate ( impl_def_id) => {
87- Ok ( ImplSource :: UserDefined ( self . confirm_impl_candidate ( obligation, impl_def_id) ) )
58+ ImplSource :: UserDefined ( self . confirm_impl_candidate ( obligation, impl_def_id) )
8859 }
8960
9061 AutoImplCandidate ( trait_def_id) => {
9162 let data = self . confirm_auto_impl_candidate ( obligation, trait_def_id) ;
92- Ok ( ImplSource :: AutoImpl ( data) )
63+ ImplSource :: AutoImpl ( data)
9364 }
9465
9566 ProjectionCandidate ( idx) => {
9667 let obligations = self . confirm_projection_candidate ( obligation, idx) ?;
9768 // FIXME(jschievink): constness
98- Ok ( ImplSource :: Param ( obligations, ty:: BoundConstness :: NotConst ) )
69+ ImplSource :: Param ( obligations, ty:: BoundConstness :: NotConst )
9970 }
10071
10172 ObjectCandidate ( idx) => {
10273 let data = self . confirm_object_candidate ( obligation, idx) ?;
103- Ok ( ImplSource :: Object ( data) )
74+ ImplSource :: Object ( data)
10475 }
10576
10677 ClosureCandidate => {
10778 let vtable_closure = self . confirm_closure_candidate ( obligation) ?;
108- Ok ( ImplSource :: Closure ( vtable_closure) )
79+ ImplSource :: Closure ( vtable_closure)
10980 }
11081
11182 GeneratorCandidate => {
11283 let vtable_generator = self . confirm_generator_candidate ( obligation) ?;
113- Ok ( ImplSource :: Generator ( vtable_generator) )
84+ ImplSource :: Generator ( vtable_generator)
11485 }
11586
11687 FnPointerCandidate { .. } => {
11788 let data = self . confirm_fn_pointer_candidate ( obligation) ?;
118- Ok ( ImplSource :: FnPointer ( data) )
89+ ImplSource :: FnPointer ( data)
11990 }
12091
12192 DiscriminantKindCandidate => {
122- Ok ( ImplSource :: DiscriminantKind ( ImplSourceDiscriminantKindData ) )
93+ ImplSource :: DiscriminantKind ( ImplSourceDiscriminantKindData )
12394 }
12495
125- PointeeCandidate => Ok ( ImplSource :: Pointee ( ImplSourcePointeeData ) ) ,
96+ PointeeCandidate => ImplSource :: Pointee ( ImplSourcePointeeData ) ,
12697
12798 TraitAliasCandidate ( alias_def_id) => {
12899 let data = self . confirm_trait_alias_candidate ( obligation, alias_def_id) ;
129- Ok ( ImplSource :: TraitAlias ( data) )
100+ ImplSource :: TraitAlias ( data)
130101 }
131102
132103 BuiltinObjectCandidate => {
133104 // This indicates something like `Trait + Send: Send`. In this case, we know that
134105 // this holds because that's what the object type is telling us, and there's really
135106 // no additional obligations to prove and no types in particular to unify, etc.
136- Ok ( ImplSource :: Param ( Vec :: new ( ) , ty:: BoundConstness :: NotConst ) )
107+ ImplSource :: Param ( Vec :: new ( ) , ty:: BoundConstness :: NotConst )
137108 }
138109
139110 BuiltinUnsizeCandidate => {
140111 let data = self . confirm_builtin_unsize_candidate ( obligation) ?;
141- Ok ( ImplSource :: Builtin ( data) )
112+ ImplSource :: Builtin ( data)
142113 }
143114
144115 TraitUpcastingUnsizeCandidate ( idx) => {
145116 let data = self . confirm_trait_upcasting_unsize_candidate ( obligation, idx) ?;
146- Ok ( ImplSource :: TraitUpcasting ( data) )
117+ ImplSource :: TraitUpcasting ( data)
147118 }
148119
149120 ConstDestructCandidate ( def_id) => {
150121 let data = self . confirm_const_destruct_candidate ( obligation, def_id) ?;
151- Ok ( ImplSource :: ConstDestruct ( data) )
122+ ImplSource :: ConstDestruct ( data)
152123 }
124+ } ;
125+
126+ if !obligation. predicate . is_const_if_const ( ) {
127+ // normalize nested predicates according to parent predicate's constness.
128+ impl_src = impl_src. map ( |mut o| {
129+ o. predicate = o. predicate . without_const ( self . tcx ( ) ) ;
130+ o
131+ } ) ;
153132 }
133+
134+ Ok ( impl_src)
154135 }
155136
156137 fn confirm_projection_candidate (
0 commit comments