@@ -42,115 +42,96 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
42
42
obligation : & TraitObligation < ' tcx > ,
43
43
candidate : SelectionCandidate < ' tcx > ,
44
44
) -> 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 {
75
46
BuiltinCandidate { has_nested } => {
76
47
let data = self . confirm_builtin_candidate ( obligation, has_nested) ;
77
- Ok ( ImplSource :: Builtin ( data) )
48
+ ImplSource :: Builtin ( data)
78
49
}
79
50
80
51
ParamCandidate ( param) => {
81
52
let obligations =
82
53
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 )
84
55
}
85
56
86
57
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) )
88
59
}
89
60
90
61
AutoImplCandidate ( trait_def_id) => {
91
62
let data = self . confirm_auto_impl_candidate ( obligation, trait_def_id) ;
92
- Ok ( ImplSource :: AutoImpl ( data) )
63
+ ImplSource :: AutoImpl ( data)
93
64
}
94
65
95
66
ProjectionCandidate ( idx) => {
96
67
let obligations = self . confirm_projection_candidate ( obligation, idx) ?;
97
68
// FIXME(jschievink): constness
98
- Ok ( ImplSource :: Param ( obligations, ty:: BoundConstness :: NotConst ) )
69
+ ImplSource :: Param ( obligations, ty:: BoundConstness :: NotConst )
99
70
}
100
71
101
72
ObjectCandidate ( idx) => {
102
73
let data = self . confirm_object_candidate ( obligation, idx) ?;
103
- Ok ( ImplSource :: Object ( data) )
74
+ ImplSource :: Object ( data)
104
75
}
105
76
106
77
ClosureCandidate => {
107
78
let vtable_closure = self . confirm_closure_candidate ( obligation) ?;
108
- Ok ( ImplSource :: Closure ( vtable_closure) )
79
+ ImplSource :: Closure ( vtable_closure)
109
80
}
110
81
111
82
GeneratorCandidate => {
112
83
let vtable_generator = self . confirm_generator_candidate ( obligation) ?;
113
- Ok ( ImplSource :: Generator ( vtable_generator) )
84
+ ImplSource :: Generator ( vtable_generator)
114
85
}
115
86
116
87
FnPointerCandidate { .. } => {
117
88
let data = self . confirm_fn_pointer_candidate ( obligation) ?;
118
- Ok ( ImplSource :: FnPointer ( data) )
89
+ ImplSource :: FnPointer ( data)
119
90
}
120
91
121
92
DiscriminantKindCandidate => {
122
- Ok ( ImplSource :: DiscriminantKind ( ImplSourceDiscriminantKindData ) )
93
+ ImplSource :: DiscriminantKind ( ImplSourceDiscriminantKindData )
123
94
}
124
95
125
- PointeeCandidate => Ok ( ImplSource :: Pointee ( ImplSourcePointeeData ) ) ,
96
+ PointeeCandidate => ImplSource :: Pointee ( ImplSourcePointeeData ) ,
126
97
127
98
TraitAliasCandidate ( alias_def_id) => {
128
99
let data = self . confirm_trait_alias_candidate ( obligation, alias_def_id) ;
129
- Ok ( ImplSource :: TraitAlias ( data) )
100
+ ImplSource :: TraitAlias ( data)
130
101
}
131
102
132
103
BuiltinObjectCandidate => {
133
104
// This indicates something like `Trait + Send: Send`. In this case, we know that
134
105
// this holds because that's what the object type is telling us, and there's really
135
106
// 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 )
137
108
}
138
109
139
110
BuiltinUnsizeCandidate => {
140
111
let data = self . confirm_builtin_unsize_candidate ( obligation) ?;
141
- Ok ( ImplSource :: Builtin ( data) )
112
+ ImplSource :: Builtin ( data)
142
113
}
143
114
144
115
TraitUpcastingUnsizeCandidate ( idx) => {
145
116
let data = self . confirm_trait_upcasting_unsize_candidate ( obligation, idx) ?;
146
- Ok ( ImplSource :: TraitUpcasting ( data) )
117
+ ImplSource :: TraitUpcasting ( data)
147
118
}
148
119
149
120
ConstDestructCandidate ( def_id) => {
150
121
let data = self . confirm_const_destruct_candidate ( obligation, def_id) ?;
151
- Ok ( ImplSource :: ConstDestruct ( data) )
122
+ ImplSource :: ConstDestruct ( data)
152
123
}
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
+ } ) ;
153
132
}
133
+
134
+ Ok ( impl_src)
154
135
}
155
136
156
137
fn confirm_projection_candidate (
0 commit comments