Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
389907a
Enforce E0719 only for trait aliases
Jules-Bertholet Sep 15, 2025
60dd0df
Address review comments
Jules-Bertholet Sep 24, 2025
5de617e
Rename ui test items
Jules-Bertholet Sep 26, 2025
9f667cd
Add `overlapping_assoc_constraints` param to `lower_bounds`
Jules-Bertholet Sep 29, 2025
1f8bef5
fix tuple child creation
Walnut356 Sep 30, 2025
50398e2
iter repeat: add tests for new count and last behavior
hkBst Sep 30, 2025
c131805
add test for trait-system-refactor-initiative/239
jdonszelmann Sep 30, 2025
422f6bb
enable tests on next-solver for rust-lang/trait-system-refactor-initi…
jdonszelmann Sep 30, 2025
b810a68
added error for closures case in impl
Kivooeo Oct 1, 2025
5ade764
Change ArrayWindows to use a slice
camsteffen Sep 30, 2025
96fb1b3
include outer_inclusive_binder of pattern types
jdonszelmann Oct 1, 2025
0435b16
swap order of resolve_coroutine_interiors and handle_opaque_type_uses
jdonszelmann Sep 30, 2025
04ae55d
implement range support in `//@ edition`
pietroalbini Apr 22, 2025
3dcbda0
Document range syntax on the rustc dev guide
pvdrz Sep 21, 2025
84864bc
Fix typo in 'unfulfilled_lint_expectation' to plural
demoray Oct 1, 2025
5cb4a8d
Rollup merge of #146166 - ferrocene:pvdrz/edition-range, r=fmease,jie…
matthiaskrgr Oct 1, 2025
b2453bb
Rollup merge of #146593 - Jules-Bertholet:restrict-e0719, r=BoxyUwU
matthiaskrgr Oct 1, 2025
949a755
Rollup merge of #147177 - Walnut356:tuples, r=Mark-Simulacrum
matthiaskrgr Oct 1, 2025
ed1e8d5
Rollup merge of #147195 - hkBst:repeat-3, r=Mark-Simulacrum
matthiaskrgr Oct 1, 2025
65ace36
Rollup merge of #147202 - jdonszelmann:swap-order, r=lcnr
matthiaskrgr Oct 1, 2025
bb6165b
Rollup merge of #147204 - camsteffen:array-windows-ref, r=joboet
matthiaskrgr Oct 1, 2025
76e2991
Rollup merge of #147219 - Kivooeo:typeof-is-imposter, r=jdonszelmann
matthiaskrgr Oct 1, 2025
2100519
Rollup merge of #147226 - jdonszelmann:pattern-types-next-solver, r=lcnr
matthiaskrgr Oct 1, 2025
578a5d6
Rollup merge of #147230 - demoray:patch-1, r=jdonszelmann
matthiaskrgr Oct 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions compiler/rustc_error_codes/src/error_codes/E0719.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
An associated type value was specified more than once.
An associated item was specified more than once in a trait object.

Erroneous code example:

Expand All @@ -7,21 +7,15 @@ trait FooTrait {}
trait BarTrait {}

// error: associated type `Item` in trait `Iterator` is specified twice
struct Foo<T: Iterator<Item: FooTrait, Item: BarTrait>> { f: T }
type Foo = dyn Iterator<Item = u32, Item = u32>;
```

`Item` in trait `Iterator` cannot be specified multiple times for struct `Foo`.
To fix this, create a new trait that is a combination of the desired traits and
specify the associated type with the new trait.
To fix this, remove the duplicate specifier:

Corrected example:

```
trait FooTrait {}
trait BarTrait {}
trait FooBarTrait: FooTrait + BarTrait {}

struct Foo<T: Iterator<Item: FooBarTrait>> { f: T } // ok!
type Foo = dyn Iterator<Item = u32>; // ok!
```

For more information about associated types, see [the book][bk-at]. For more
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,10 @@ impl<'tcx> InherentCollect<'tcx> {
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::Alias(ty::Free, _)
| ty::Bound(..)
| ty::Placeholder(_)
| ty::Infer(_) => {
| ty::CoroutineWitness(..) => {
Err(self.tcx.dcx().delayed_bug("cannot define inherent `impl` for closure types"))
}
ty::Alias(ty::Free, _) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) => {
bug!("unexpected impl self type of impl: {:?} {:?}", id, self_ty);
}
// We could bail out here, but that will silence other useful errors.
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_hir_analysis/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,12 @@ pub(crate) fn orphan_check_impl(
ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::Bound(..)
| ty::Placeholder(..)
| ty::Infer(..) => {
| ty::CoroutineWitness(..) => {
return Err(tcx
.dcx()
.delayed_bug("cannot define inherent `impl` for closure types"));
}
ty::Bound(..) | ty::Placeholder(..) | ty::Infer(..) => {
let sp = tcx.def_span(impl_def_id);
span_bug!(sp, "weird self type for autotrait impl")
}
Expand Down
20 changes: 17 additions & 3 deletions compiler/rustc_hir_analysis/src/collect/item_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use tracing::{debug, instrument};

use super::ItemCtxt;
use super::predicates_of::assert_only_contains_predicates_from;
use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter};
use crate::hir_ty_lowering::{HirTyLowerer, OverlappingAsssocItemConstraints, PredicateFilter};

/// For associated types we include both bounds written on the type
/// (`type X: Trait`) and predicates from the trait: `where Self::X: Trait`.
Expand All @@ -37,7 +37,14 @@ fn associated_type_bounds<'tcx>(

let icx = ItemCtxt::new(tcx, assoc_item_def_id);
let mut bounds = Vec::new();
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
icx.lowerer().lower_bounds(
item_ty,
hir_bounds,
&mut bounds,
ty::List::empty(),
filter,
OverlappingAsssocItemConstraints::Allowed,
);

match filter {
PredicateFilter::All
Expand Down Expand Up @@ -347,7 +354,14 @@ fn opaque_type_bounds<'tcx>(
ty::print::with_reduced_queries!({
let icx = ItemCtxt::new(tcx, opaque_def_id);
let mut bounds = Vec::new();
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
icx.lowerer().lower_bounds(
item_ty,
hir_bounds,
&mut bounds,
ty::List::empty(),
filter,
OverlappingAsssocItemConstraints::Allowed,
);
// Implicit bounds are added to opaque types unless a `?Trait` bound is found
match filter {
PredicateFilter::All
Expand Down
18 changes: 16 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ use super::item_bounds::explicit_item_bounds_with_filter;
use crate::collect::ItemCtxt;
use crate::constrained_generic_params as cgp;
use crate::delegation::inherit_predicates_for_delegation_item;
use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter, RegionInferReason};
use crate::hir_ty_lowering::{
HirTyLowerer, OverlappingAsssocItemConstraints, PredicateFilter, RegionInferReason,
};

/// Returns a list of all type predicates (explicit and implicit) for the definition with
/// ID `def_id`. This includes all predicates returned by `explicit_predicates_of`, plus
Expand Down Expand Up @@ -187,6 +189,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
&mut bounds,
ty::List::empty(),
PredicateFilter::All,
OverlappingAsssocItemConstraints::Allowed,
);
icx.lowerer().add_sizedness_bounds(
&mut bounds,
Expand Down Expand Up @@ -289,6 +292,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
&mut bounds,
bound_vars,
PredicateFilter::All,
OverlappingAsssocItemConstraints::Allowed,
);
predicates.extend(bounds);
}
Expand Down Expand Up @@ -659,7 +663,14 @@ pub(super) fn implied_predicates_with_filter<'tcx>(

let self_param_ty = tcx.types.self_param;
let mut bounds = Vec::new();
icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter);
icx.lowerer().lower_bounds(
self_param_ty,
superbounds,
&mut bounds,
ty::List::empty(),
filter,
OverlappingAsssocItemConstraints::Allowed,
);
match filter {
PredicateFilter::All
| PredicateFilter::SelfOnly
Expand Down Expand Up @@ -984,6 +995,7 @@ impl<'tcx> ItemCtxt<'tcx> {
&mut bounds,
bound_vars,
filter,
OverlappingAsssocItemConstraints::Allowed,
);
}

Expand Down Expand Up @@ -1063,6 +1075,7 @@ pub(super) fn const_conditions<'tcx>(
&mut bounds,
bound_vars,
PredicateFilter::ConstIfConst,
OverlappingAsssocItemConstraints::Allowed,
);
}
_ => {}
Expand All @@ -1083,6 +1096,7 @@ pub(super) fn const_conditions<'tcx>(
&mut bounds,
ty::List::empty(),
PredicateFilter::ConstIfConst,
OverlappingAsssocItemConstraints::Allowed,
);
}

Expand Down
32 changes: 19 additions & 13 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ use tracing::{debug, instrument};
use super::errors::GenericsArgsErrExtend;
use crate::errors;
use crate::hir_ty_lowering::{
AssocItemQSelf, FeedConstTy, HirTyLowerer, PredicateFilter, RegionInferReason,
AssocItemQSelf, FeedConstTy, HirTyLowerer, OverlappingAsssocItemConstraints, PredicateFilter,
RegionInferReason,
};

#[derive(Debug, Default)]
Expand Down Expand Up @@ -338,6 +339,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
predicate_filter: PredicateFilter,
overlapping_assoc_constraints: OverlappingAsssocItemConstraints,
) where
'tcx: 'hir,
{
Expand All @@ -362,6 +364,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
param_ty,
bounds,
predicate_filter,
overlapping_assoc_constraints,
);
}
hir::GenericBound::Outlives(lifetime) => {
Expand Down Expand Up @@ -402,7 +405,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
trait_ref: ty::PolyTraitRef<'tcx>,
constraint: &hir::AssocItemConstraint<'tcx>,
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
duplicates: &mut FxIndexMap<DefId, Span>,
duplicates: Option<&mut FxIndexMap<DefId, Span>>,
path_span: Span,
predicate_filter: PredicateFilter,
) -> Result<(), ErrorGuaranteed> {
Expand Down Expand Up @@ -458,17 +461,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
)
.expect("failed to find associated item");

duplicates
.entry(assoc_item.def_id)
.and_modify(|prev_span| {
self.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
span: constraint.span,
prev_span: *prev_span,
item_name: constraint.ident,
def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
});
})
.or_insert(constraint.span);
if let Some(duplicates) = duplicates {
duplicates
.entry(assoc_item.def_id)
.and_modify(|prev_span| {
self.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
span: constraint.span,
prev_span: *prev_span,
item_name: constraint.ident,
def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
});
})
.or_insert(constraint.span);
}

let projection_term = if let ty::AssocTag::Fn = assoc_tag {
let bound_vars = tcx.late_bound_vars(constraint.hir_id);
Expand Down Expand Up @@ -600,6 +605,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
bounds,
projection_ty.bound_vars(),
predicate_filter,
OverlappingAsssocItemConstraints::Allowed,
);
}
PredicateFilter::SelfOnly
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ use tracing::{debug, instrument};

use super::HirTyLowerer;
use crate::errors::SelfInTypeAlias;
use crate::hir_ty_lowering::{GenericArgCountMismatch, PredicateFilter, RegionInferReason};
use crate::hir_ty_lowering::{
GenericArgCountMismatch, OverlappingAsssocItemConstraints, PredicateFilter, RegionInferReason,
};

impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Lower a trait object type from the HIR to our internal notion of a type.
Expand Down Expand Up @@ -60,6 +62,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
dummy_self,
&mut user_written_bounds,
PredicateFilter::SelfOnly,
OverlappingAsssocItemConstraints::Forbidden,
);
if let Err(GenericArgCountMismatch { invalid_args, .. }) = result.correct {
potential_assoc_types.extend(invalid_args);
Expand Down Expand Up @@ -157,10 +160,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
self.dcx()
.struct_span_err(
span,
format!(
"conflicting associated type bounds for `{item}` when \
expanding trait alias"
),
format!("conflicting associated type bounds for `{item}`"),
)
.with_span_label(
old_proj_span,
Expand Down
18 changes: 16 additions & 2 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,15 @@ pub(crate) enum GenericArgPosition {
MethodCall,
}

/// Whether to allow duplicate associated iten constraints in a trait ref, e.g.
/// `Trait<Assoc = Ty, Assoc = Ty>`. This is forbidden in `dyn Trait<...>`
/// but allowed everywhere else.
#[derive(Clone, Copy, Debug, PartialEq)]
pub(crate) enum OverlappingAsssocItemConstraints {
Allowed,
Forbidden,
}

/// A marker denoting that the generic arguments that were
/// provided did not match the respective generic parameters.
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -752,6 +761,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
self_ty: Ty<'tcx>,
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
predicate_filter: PredicateFilter,
overlapping_assoc_item_constraints: OverlappingAsssocItemConstraints,
) -> GenericArgCountResult {
let tcx = self.tcx();

Expand Down Expand Up @@ -908,7 +918,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
}

let mut dup_constraints = FxIndexMap::default();
let mut dup_constraints = (overlapping_assoc_item_constraints
== OverlappingAsssocItemConstraints::Forbidden)
.then_some(FxIndexMap::default());

for constraint in trait_segment.args().constraints {
// Don't register any associated item constraints for negative bounds,
// since we should have emitted an error for them earlier, and they
Expand All @@ -927,7 +940,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
poly_trait_ref,
constraint,
bounds,
&mut dup_constraints,
dup_constraints.as_mut(),
constraint.span,
predicate_filter,
);
Expand Down Expand Up @@ -2484,6 +2497,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
&mut bounds,
ty::List::empty(),
PredicateFilter::All,
OverlappingAsssocItemConstraints::Allowed,
);
self.add_sizedness_bounds(
&mut bounds,
Expand Down
18 changes: 6 additions & 12 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,19 +611,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
typeck_results.rvalue_scopes = rvalue_scopes;
}

/// Unify the inference variables corresponding to coroutine witnesses, and save all the
/// predicates that were stalled on those inference variables.
///
/// This process allows to conservatively save all predicates that do depend on the coroutine
/// interior types, for later processing by `check_coroutine_obligations`.
///
/// We must not attempt to select obligations after this method has run, or risk query cycle
/// ICE.
/// Drain all obligations that are stalled on coroutines defined in this body.
#[instrument(level = "debug", skip(self))]
pub(crate) fn resolve_coroutine_interiors(&self) {
// Try selecting all obligations that are not blocked on inference variables.
// Once we start unifying coroutine witnesses, trying to select obligations on them will
// trigger query cycle ICEs, as doing so requires MIR.
pub(crate) fn drain_stalled_coroutine_obligations(&self) {
// Make as much inference progress as possible before
// draining the stalled coroutine obligations as this may
// change obligations from being stalled on infer vars to
// being stalled on a coroutine.
self.select_obligations_where_possible(|_| {});

let ty::TypingMode::Analysis { defining_opaque_types_and_generators } = self.typing_mode()
Expand Down
9 changes: 3 additions & 6 deletions compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,18 +243,15 @@ fn typeck_with_inspect<'tcx>(

debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());

// This must be the last thing before `report_ambiguity_errors`.
fcx.resolve_coroutine_interiors();

debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());

// We need to handle opaque types before emitting ambiguity errors as applying
// defining uses may guide type inference.
if fcx.next_trait_solver() {
fcx.handle_opaque_type_uses_next();
}

fcx.select_obligations_where_possible(|_| {});
// This must be the last thing before `report_ambiguity_errors` below except `select_obligations_where_possible`.
// So don't put anything after this.
fcx.drain_stalled_coroutine_obligations();
if fcx.infcx.tainted_by_errors().is_none() {
fcx.report_ambiguity_errors();
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_type_ir/src/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ impl<I: Interner> FlagComputation<I> {

fn add_ty_pat(&mut self, pat: <I as Interner>::Pat) {
self.add_flags(pat.flags());
self.add_exclusive_binder(pat.outer_exclusive_binder());
}

fn add_predicate(&mut self, binder: ty::Binder<I, ty::PredicateKind<I>>) {
Expand Down
Loading
Loading