rust-lang/rust · error

missing QSelf for <T>::...

Error message

missing QSelf for <T>::...

What it means

path.rs:168: when lowering a path with associated projections (unresolved_segments != 0) and an empty base path, the code does qself.expect("missing QSelf for <T>::..."). The invariant: an empty base path with trailing projections implies a syntactic Self (e.g. `<&i32>::clone`), so a QSelf must be present.

Source

Thrown at compiler/rustc_ast_lowering/src/path.rs:168

        if let Some(bound_modifier_allowed_features) = bound_modifier_allowed_features {
            path.span = self.mark_span_with_reason(
                DesugaringKind::BoundModifier,
                path.span,
                Some(bound_modifier_allowed_features),
            );
        }

        // Simple case, either no projections, or only fully-qualified.
        // E.g., `std::mem::size_of` or `<I as Iterator>::Item`.
        if unresolved_segments == 0 {
            return hir::QPath::Resolved(qself, path);
        }

        // Create the innermost type that we're projecting from.
        let mut ty = if path.segments.is_empty() {
            // If the base path is empty that means there exists a
            // syntactical `Self`, e.g., `&i32` in `<&i32>::clone`.
            qself.expect("missing QSelf for <T>::...")
        } else {
            // Otherwise, the base path is an implicit `Self` type path,
            // e.g., `Vec` in `Vec::new` or `<I as Iterator>::Item` in
            // `<I as Iterator>::Item::default`.
            let new_id = self.next_id();
            self.arena.alloc(self.ty_path(new_id, path.span, hir::QPath::Resolved(qself, path)))
        };

        // Anything after the base path are associated "extensions",
        // out of which all but the last one are associated types,
        // e.g., for `std::vec::Vec::<T>::IntoIter::Item::clone`:
        // * base path is `std::vec::Vec<T>`
        // * "extensions" are `IntoIter`, `Item` and `clone`
        // * type nodes are:
        //   1. `std::vec::Vec<T>` (created above)
        //   2. `<std::vec::Vec<T>>::IntoIter`
        //   3. `<<std::vec::Vec<T>>::IntoIter>::Item`
        // * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. File a rustc ICE with the minimized path expression that triggers it.
  2. Rewrite the associated path to avoid the empty-base-with-projection form (use an explicit type base).
  3. Bisect across nightlies with cargo bisect-rustc.
  4. Try the equivalent code on stable to confirm it is a regression.
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: Path lowering encounters a `<...>::proj` form where the base segments are empty but qself is None, an inconsistent state produced by an earlier lowering/resolution step.

Common situations: Compiler bug in path lowering for fully-qualified associated paths; not reachable from well-formed source.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/f0912a7cf081e541. Report an issue: GitHub.