Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6102cbb

Browse files
authoredMar 21, 2025··
Unrolled build for rust-lang#138727
Rollup merge of rust-lang#138727 - compiler-errors:ty-var-origin, r=fmease Do not rely on `type_var_origin` in `OrphanCheckErr::NonLocalInputType` The ordering of ty var unification means that we may end up with a root variable whose ty var origin is from another item's params. Let's not rely on this by just unifying the infer vars with the params of the impl + resolving. It's kinda goofy but it's clearer IMO. Fixes rust-lang#132826. r? `@fmease` or `@lcnr`
2 parents 78948ac + 220851c commit 6102cbb

File tree

6 files changed

+60
-64
lines changed

6 files changed

+60
-64
lines changed
 

‎compiler/rustc_hir_analysis/src/coherence/orphan.rs

+16-47
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
44
use rustc_data_structures::fx::FxIndexSet;
55
use rustc_errors::ErrorGuaranteed;
6-
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
6+
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
77
use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION;
88
use rustc_middle::ty::{
9-
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable,
10-
TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
9+
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
1110
};
1211
use rustc_middle::{bug, span_bug};
1312
use rustc_span::def_id::{DefId, LocalDefId};
@@ -356,13 +355,20 @@ fn orphan_check<'tcx>(
356355
})
357356
}
358357
OrphanCheckErr::NonLocalInputType(tys) => {
359-
let generics = tcx.generics_of(impl_def_id);
360-
let tys = tys
361-
.into_iter()
362-
.map(|(ty, is_target_ty)| {
363-
(ty.fold_with(&mut TyVarReplacer { infcx: &infcx, generics }), is_target_ty)
364-
})
365-
.collect();
358+
let tys = infcx.probe(|_| {
359+
// Map the unconstrained args back to their params,
360+
// ignoring any type unification errors.
361+
for (arg, id_arg) in
362+
std::iter::zip(args, ty::GenericArgs::identity_for_item(tcx, impl_def_id))
363+
{
364+
let _ = infcx.at(&cause, ty::ParamEnv::empty()).eq(
365+
DefineOpaqueTypes::No,
366+
arg,
367+
id_arg,
368+
);
369+
}
370+
infcx.resolve_vars_if_possible(tys)
371+
});
366372
OrphanCheckErr::NonLocalInputType(tys)
367373
}
368374
})
@@ -536,40 +542,3 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UncoveredTyParamCollector<'_, 'tcx> {
536542
}
537543
}
538544
}
539-
540-
struct TyVarReplacer<'cx, 'tcx> {
541-
infcx: &'cx InferCtxt<'tcx>,
542-
generics: &'tcx ty::Generics,
543-
}
544-
545-
impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for TyVarReplacer<'cx, 'tcx> {
546-
fn cx(&self) -> TyCtxt<'tcx> {
547-
self.infcx.tcx
548-
}
549-
550-
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
551-
if !ty.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
552-
return ty;
553-
}
554-
let ty::Infer(ty::TyVar(vid)) = *ty.kind() else {
555-
return ty.super_fold_with(self);
556-
};
557-
let origin = self.infcx.type_var_origin(vid);
558-
if let Some(def_id) = origin.param_def_id {
559-
// The generics of an `impl` don't have a parent, we can index directly.
560-
let index = self.generics.param_def_id_to_index[&def_id];
561-
let name = self.generics.own_params[index as usize].name;
562-
563-
Ty::new_param(self.infcx.tcx, index, name)
564-
} else {
565-
ty
566-
}
567-
}
568-
569-
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
570-
if !ct.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
571-
return ct;
572-
}
573-
ct.super_fold_with(self)
574-
}
575-
}

‎compiler/rustc_next_trait_solver/src/coherence.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use std::ops::ControlFlow;
44
use derive_where::derive_where;
55
use rustc_type_ir::inherent::*;
66
use rustc_type_ir::{
7-
self as ty, InferCtxtLike, Interner, TypeVisitable, TypeVisitableExt, TypeVisitor,
7+
self as ty, InferCtxtLike, Interner, TrivialTypeTraversalImpls, TypeVisitable,
8+
TypeVisitableExt, TypeVisitor,
89
};
910
use tracing::instrument;
1011

@@ -95,6 +96,8 @@ pub fn trait_ref_is_local_or_fundamental<I: Interner>(tcx: I, trait_ref: ty::Tra
9596
trait_ref.def_id.is_local() || tcx.trait_is_fundamental(trait_ref.def_id)
9697
}
9798

99+
TrivialTypeTraversalImpls! { IsFirstInputType, }
100+
98101
#[derive(Debug, Copy, Clone)]
99102
pub enum IsFirstInputType {
100103
No,

‎compiler/rustc_type_ir/src/macros.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,34 @@
11
/// Used for types that are `Copy` and which **do not care arena
22
/// allocated data** (i.e., don't need to be folded).
3+
#[macro_export]
34
macro_rules! TrivialTypeTraversalImpls {
45
($($ty:ty,)+) => {
56
$(
6-
impl<I: $crate::Interner> $crate::fold::TypeFoldable<I> for $ty {
7-
fn try_fold_with<F: $crate::fold::FallibleTypeFolder<I>>(
7+
impl<I: $crate::Interner> $crate::TypeFoldable<I> for $ty {
8+
fn try_fold_with<F: $crate::FallibleTypeFolder<I>>(
89
self,
910
_: &mut F,
1011
) -> ::std::result::Result<Self, F::Error> {
1112
Ok(self)
1213
}
1314

1415
#[inline]
15-
fn fold_with<F: $crate::fold::TypeFolder<I>>(
16+
fn fold_with<F: $crate::TypeFolder<I>>(
1617
self,
1718
_: &mut F,
1819
) -> Self {
1920
self
2021
}
2122
}
2223

23-
impl<I: $crate::Interner> $crate::visit::TypeVisitable<I> for $ty {
24+
impl<I: $crate::Interner> $crate::TypeVisitable<I> for $ty {
2425
#[inline]
25-
fn visit_with<F: $crate::visit::TypeVisitor<I>>(
26+
fn visit_with<F: $crate::TypeVisitor<I>>(
2627
&self,
2728
_: &mut F)
2829
-> F::Result
2930
{
30-
<F::Result as rustc_ast_ir::visit::VisitorResult>::output()
31+
<F::Result as $crate::VisitorResult>::output()
3132
}
3233
}
3334
)+

‎tests/crashes/132826.rs

-10
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Regression test for #132826.
2+
3+
// Make sure we don't try to resolve the variable `K1` in the generics of the impl
4+
// (which only has `K2`).
5+
6+
pub trait MyTrait {
7+
type Item;
8+
}
9+
10+
impl<K1> MyTrait for Vec<K1> {
11+
type Item = Vec<K1>;
12+
}
13+
14+
impl<K2> From<Vec<K2>> for <Vec<K2> as MyTrait>::Item {}
15+
//~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
2+
--> $DIR/orphan-check-error-reporting-ty-var.rs:14:1
3+
|
4+
LL | impl<K2> From<Vec<K2>> for <Vec<K2> as MyTrait>::Item {}
5+
| ^^^^^^^^^-------------^^^^^--------------------------
6+
| | |
7+
| | `Vec` is not defined in the current crate
8+
| `Vec` is not defined in the current crate
9+
|
10+
= note: impl doesn't have any local type before any uncovered type parameters
11+
= note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
12+
= note: define and implement a trait or new type instead
13+
14+
error: aborting due to 1 previous error
15+
16+
For more information about this error, try `rustc --explain E0117`.

0 commit comments

Comments
 (0)
Please sign in to comment.