Skip to content

Commit d744f36

Browse files
committed
Fix wf check on #[const_trait] return types
1 parent a9bb589 commit d744f36

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

compiler/rustc_typeck/src/check/wfcheck.rs

+32-6
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,18 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
6666
span: Span,
6767
loc: Option<WellFormedLoc>,
6868
arg: ty::GenericArg<'tcx>,
69+
override_constness: Option<hir::Constness>,
6970
) {
7071
let cause =
7172
traits::ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(loc));
73+
let param_env = if let Some(constness) = override_constness {
74+
self.param_env.with_constness(constness)
75+
} else {
76+
self.param_env
77+
};
7278
self.ocx.register_obligation(traits::Obligation::new(
7379
cause,
74-
self.param_env,
80+
param_env,
7581
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(self.tcx()),
7682
));
7783
}
@@ -985,7 +991,7 @@ fn check_associated_item(
985991
ty::AssocKind::Const => {
986992
let ty = tcx.type_of(item.def_id);
987993
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
988-
wfcx.register_wf_obligation(span, loc, ty.into());
994+
wfcx.register_wf_obligation(span, loc, ty.into(), None);
989995
}
990996
ty::AssocKind::Fn => {
991997
let sig = tcx.fn_sig(item.def_id);
@@ -1006,7 +1012,7 @@ fn check_associated_item(
10061012
if item.defaultness(tcx).has_value() {
10071013
let ty = tcx.type_of(item.def_id);
10081014
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
1009-
wfcx.register_wf_obligation(span, loc, ty.into());
1015+
wfcx.register_wf_obligation(span, loc, ty.into(), None);
10101016
}
10111017
}
10121018
}
@@ -1042,6 +1048,7 @@ fn check_type_defn<'tcx, F>(
10421048
field.span,
10431049
Some(WellFormedLoc::Ty(field.def_id)),
10441050
field.ty.into(),
1051+
None,
10451052
)
10461053
}
10471054

@@ -1191,7 +1198,12 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: LocalDefId, ty_span: Span, allow_fo
11911198
}
11921199
}
11931200

1194-
wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(item_id)), item_ty.into());
1201+
wfcx.register_wf_obligation(
1202+
ty_span,
1203+
Some(WellFormedLoc::Ty(item_id)),
1204+
item_ty.into(),
1205+
None,
1206+
);
11951207
if forbid_unsized {
11961208
wfcx.register_bound(
11971209
traits::ObligationCause::new(ty_span, wfcx.body_id, traits::WellFormed(None)),
@@ -1260,6 +1272,7 @@ fn check_impl<'tcx>(
12601272
ast_self_ty.span,
12611273
Some(WellFormedLoc::Ty(item.hir_id().expect_owner())),
12621274
self_ty.into(),
1275+
None,
12631276
);
12641277
}
12651278
}
@@ -1300,7 +1313,12 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
13001313
// parameter includes another (e.g., `<T, U = T>`). In those cases, we can't
13011314
// be sure if it will error or not as user might always specify the other.
13021315
if !ty.needs_subst() {
1303-
wfcx.register_wf_obligation(tcx.def_span(param.def_id), None, ty.into());
1316+
wfcx.register_wf_obligation(
1317+
tcx.def_span(param.def_id),
1318+
None,
1319+
ty.into(),
1320+
None,
1321+
);
13041322
}
13051323
}
13061324
}
@@ -1316,6 +1334,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
13161334
tcx.def_span(param.def_id),
13171335
None,
13181336
default_ct.into(),
1337+
None,
13191338
);
13201339
}
13211340
}
@@ -1496,10 +1515,17 @@ fn check_fn_or_method<'tcx>(
14961515
ty.span,
14971516
Some(WellFormedLoc::Param { function: def_id, param_idx: i.try_into().unwrap() }),
14981517
input_ty.into(),
1518+
None,
14991519
);
15001520
}
15011521

1502-
wfcx.register_wf_obligation(hir_decl.output.span(), None, sig.output().into());
1522+
// override the env when checking the return type. `~const` bounds can be fulfilled with non-const implementations.
1523+
wfcx.register_wf_obligation(
1524+
hir_decl.output.span(),
1525+
None,
1526+
sig.output().into(),
1527+
Some(hir::Constness::NotConst),
1528+
);
15031529

15041530
check_where_clauses(wfcx, span, def_id);
15051531
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// check-pass
2+
#![feature(const_trait_impl)]
3+
4+
#[const_trait]
5+
pub trait Index {
6+
type Output;
7+
}
8+
9+
#[const_trait]
10+
pub trait IndexMut where Self: Index {
11+
fn foo(&mut self) -> <Self as Index>::Output;
12+
}
13+
14+
fn main() {}

0 commit comments

Comments
 (0)