Auto merge of #114545 - fee1-dead-contrib:lower-impl-effect, r=oli-obk

correctly lower `impl const` to bind to host effect param

r? `@oli-obk`
This commit is contained in:
bors 2023-08-08 19:23:41 +00:00
commit f88a8b71ce
64 changed files with 465 additions and 373 deletions

View file

@ -532,6 +532,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if let Err(guar) = ty.error_reported() {
return ty::Const::new_error(tcx, guar, ty).into();
}
// FIXME(effects) see if we should special case effect params here
if !infer_args && has_default {
tcx.const_param_default(param.def_id)
.instantiate(tcx, args.unwrap())
@ -659,7 +660,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
&self,
trait_ref: &hir::TraitRef<'_>,
self_ty: Ty<'tcx>,
constness: ty::BoundConstness,
) -> ty::TraitRef<'tcx> {
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
@ -669,7 +669,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self_ty,
trait_ref.path.segments.last().unwrap(),
true,
constness,
ty::BoundConstness::NotConst,
)
}
@ -849,6 +849,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self_ty: Ty<'tcx>,
trait_segment: &hir::PathSegment<'_>,
is_impl: bool,
// FIXME(effects) move all host param things in astconv to hir lowering
constness: ty::BoundConstness,
) -> ty::TraitRef<'tcx> {
let (generic_args, _) = self.create_args_for_ast_trait_ref(
@ -2714,11 +2715,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
};
let i = hir.get_parent(fn_hir_id).expect_item().expect_impl();
let trait_ref = self.instantiate_mono_trait_ref(
i.of_trait.as_ref()?,
self.ast_ty_to_ty(i.self_ty),
ty::BoundConstness::NotConst,
);
let trait_ref =
self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty));
let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind(
tcx,

View file

@ -1359,38 +1359,60 @@ fn impl_trait_ref(
.as_ref()
.map(|ast_trait_ref| {
let selfty = tcx.type_of(def_id).instantiate_identity();
icx.astconv().instantiate_mono_trait_ref(
ast_trait_ref,
selfty,
check_impl_constness(tcx, impl_.constness, ast_trait_ref),
)
if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
tcx,
tcx.is_const_trait_impl_raw(def_id.to_def_id()),
&ast_trait_ref,
) {
// we have a const impl, but for a trait without `#[const_trait]`, so
// without the host param. If we continue with the HIR trait ref, we get
// ICEs for generic arg count mismatch. We do a little HIR editing to
// make astconv happy.
let mut path_segments = ast_trait_ref.path.segments.to_vec();
let last_segment = path_segments.len() - 1;
let mut args = path_segments[last_segment].args().clone();
let last_arg = args.args.len() - 1;
assert!(matches!(args.args[last_arg], hir::GenericArg::Const(anon_const) if tcx.has_attr(anon_const.value.def_id, sym::rustc_host)));
args.args = &args.args[..args.args.len() - 1];
path_segments[last_segment].args = Some(&args);
let path = hir::Path {
span: ast_trait_ref.path.span,
res: ast_trait_ref.path.res,
segments: &path_segments,
};
let trait_ref = hir::TraitRef { path: &path, hir_ref_id: ast_trait_ref.hir_ref_id };
icx.astconv().instantiate_mono_trait_ref(&trait_ref, selfty)
} else {
icx.astconv().instantiate_mono_trait_ref(&ast_trait_ref, selfty)
}
})
.map(ty::EarlyBinder::bind)
}
fn check_impl_constness(
tcx: TyCtxt<'_>,
constness: hir::Constness,
is_const: bool,
ast_trait_ref: &hir::TraitRef<'_>,
) -> ty::BoundConstness {
match constness {
hir::Constness::Const => {
if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) {
let trait_name = tcx.item_name(trait_def_id).to_string();
tcx.sess.emit_err(errors::ConstImplForNonConstTrait {
trait_ref_span: ast_trait_ref.path.span,
trait_name,
local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
marking: (),
adding: (),
});
ty::BoundConstness::NotConst
} else {
ty::BoundConstness::ConstIfConst
}
},
hir::Constness::NotConst => ty::BoundConstness::NotConst,
) -> Option<ErrorGuaranteed> {
if !is_const {
return None;
}
let trait_def_id = ast_trait_ref.trait_def_id()?;
if tcx.has_attr(trait_def_id, sym::const_trait) {
return None;
}
let trait_name = tcx.item_name(trait_def_id).to_string();
Some(tcx.sess.emit_err(errors::ConstImplForNonConstTrait {
trait_ref_span: ast_trait_ref.path.span,
trait_name,
local_trait_span:
trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
marking: (),
adding: (),
}))
}
fn impl_polarity(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplPolarity {

View file

@ -320,7 +320,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
bug!("parent also has host effect param? index: {idx}, def: {def_id:?}");
}
host_effect_index = Some(parent_count + index as usize);
host_effect_index = Some(index as usize);
}
Some(ty::GenericParamDef {

View file

@ -578,6 +578,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
MissingTypesOrConsts { .. } => {
self.suggest_adding_type_and_const_args(err);
}
ExcessTypesOrConsts { .. } => {
// this can happen with `~const T` where T isn't a const_trait.
}
_ => unreachable!(),
}
}