Skip to content

Commit 814df6e

Browse files
committed
Auto merge of rust-lang#131840 - compiler-errors:impossible-maybe, r=lcnr
Dont consider predicates that may hold as impossible in `is_impossible_associated_item` Use infer vars to account for ambiguities when considering if methods are impossible to instantiate for a given self type. Also while we're at it, let's use the new trait solver instead of `evaluate` since this is used in rustdoc. r? lcnr Fixes rust-lang#131839
2 parents 4392847 + 8ff8f78 commit 814df6e

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

compiler/rustc_trait_selection/src/traits/mod.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -562,11 +562,20 @@ fn is_impossible_associated_item(
562562

563563
let generics = tcx.generics_of(trait_item_def_id);
564564
let predicates = tcx.predicates_of(trait_item_def_id);
565+
566+
// Be conservative in cases where we have `W<T: ?Sized>` and a method like `Self: Sized`,
567+
// since that method *may* have some substitutions where the predicates hold.
568+
//
569+
// This replicates the logic we use in coherence.
570+
let infcx =
571+
tcx.infer_ctxt().ignoring_regions().with_next_trait_solver(true).intercrate(true).build();
572+
let param_env = ty::ParamEnv::empty();
573+
let fresh_args = infcx.fresh_args_for_item(tcx.def_span(impl_def_id), impl_def_id);
574+
565575
let impl_trait_ref = tcx
566576
.impl_trait_ref(impl_def_id)
567577
.expect("expected impl to correspond to trait")
568-
.instantiate_identity();
569-
let param_env = tcx.param_env(impl_def_id);
578+
.instantiate(tcx, fresh_args);
570579

571580
let mut visitor = ReferencesOnlyParentGenerics { tcx, generics, trait_item_def_id };
572581
let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| {
@@ -580,16 +589,9 @@ fn is_impossible_associated_item(
580589
})
581590
});
582591

583-
let infcx = tcx.infer_ctxt().ignoring_regions().build();
584-
for obligation in predicates_for_trait {
585-
// Ignore overflow error, to be conservative.
586-
if let Ok(result) = infcx.evaluate_obligation(&obligation)
587-
&& !result.may_apply()
588-
{
589-
return true;
590-
}
591-
}
592-
false
592+
let ocx = ObligationCtxt::new(&infcx);
593+
ocx.register_obligations(predicates_for_trait);
594+
!ocx.select_where_possible().is_empty()
593595
}
594596

595597
pub fn provide(providers: &mut Providers) {

tests/rustdoc/impossible-default.rs

+8
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,11 @@ pub trait Foo {
1818
pub struct Bar([u8]);
1919

2020
impl Foo for Bar {}
21+
22+
//@ has foo/struct.Generic.html '//*[@id="method.needs_sized"]//h4[@class="code-header"]' \
23+
// "fn needs_sized"
24+
//@ has foo/struct.Generic.html '//*[@id="method.no_needs_sized"]//h4[@class="code-header"]' \
25+
// "fn no_needs_sized"
26+
pub struct Generic<T: ?Sized>(T);
27+
28+
impl<T: ?Sized> Foo for Generic<T> {}

0 commit comments

Comments
 (0)