Skip to content
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9d5c74e
Do not suggest adding `;` when `,` is also a choice
compiler-errors Jul 2, 2022
cefaa9f
Re-enable submodule archive downloads.
ehuss Jul 26, 2022
4233a13
suggest a positional formatting argument instead of a captured argument
TaKO8Ki Aug 2, 2022
a0a2ec3
add tests for `Debug` formatters and precision formatters
TaKO8Ki Aug 3, 2022
e21624d
Add bound_predicates_of and bound_explicit_predicates_of
jackh726 Aug 3, 2022
96a69dc
Change sized_constraints to return EarlyBinder
jackh726 Aug 3, 2022
955fcad
Add bound_impl_subject and bound_return_ty
jackh726 Aug 3, 2022
dcd70c0
return when captured argument is not a struct field
TaKO8Ki Aug 4, 2022
a442c1e
remove Clean trait implementation for hir::FnRetTy
GuillaumeGomez Aug 4, 2022
008693d
remove Clean trait implementation for hir::TraitRef
GuillaumeGomez Aug 4, 2022
8dd44f1
Enable unused_parens for match arms
wcampbell0x2a Aug 3, 2022
8c85c99
add a comment about what we can parse now
TaKO8Ki Aug 4, 2022
cdbe956
RustWrapper: update for TypedPointerType in LLVM
durin42 Aug 4, 2022
f6ea143
Rollup merge of #98796 - compiler-errors:no-semi-if-comma, r=estebank
matthiaskrgr Aug 4, 2022
87dd56f
Rollup merge of #99772 - ehuss:reenable-submodule-archive, r=Mark-Sim…
matthiaskrgr Aug 4, 2022
d3aa757
Rollup merge of #100058 - TaKO8Ki:suggest-positional-formatting-argum…
matthiaskrgr Aug 4, 2022
6b938c8
Rollup merge of #100093 - wcampbell0x2a:unused-parens-for-match-arms,…
matthiaskrgr Aug 4, 2022
01ccde5
Rollup merge of #100095 - jackh726:early-binder, r=lcnr
matthiaskrgr Aug 4, 2022
60d83e7
Rollup merge of #100138 - GuillaumeGomez:rm-clean-impls, r=notriddle
matthiaskrgr Aug 4, 2022
c2d7321
Rollup merge of #100148 - durin42:llvm-16-pointertype, r=nikic
matthiaskrgr Aug 4, 2022
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
2 changes: 1 addition & 1 deletion compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
@@ -377,7 +377,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere

fn print_string(&mut self, st: &str, style: ast::StrStyle) {
let st = match style {
ast::StrStyle::Cooked => (format!("\"{}\"", st.escape_debug())),
ast::StrStyle::Cooked => format!("\"{}\"", st.escape_debug()),
ast::StrStyle::Raw(n) => {
format!("r{delim}\"{string}\"{delim}", delim = "#".repeat(n as usize), string = st)
}
32 changes: 16 additions & 16 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
@@ -16,9 +16,7 @@ use rustc_middle::mir::{
FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
};
use rustc_middle::ty::{
self, subst::Subst, suggest_constraining_type_params, EarlyBinder, PredicateKind, Ty,
};
use rustc_middle::ty::{self, subst::Subst, suggest_constraining_type_params, PredicateKind, Ty};
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
use rustc_span::def_id::LocalDefId;
use rustc_span::hygiene::DesugaringKind;
@@ -461,35 +459,37 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let tcx = self.infcx.tcx;

// Find out if the predicates show that the type is a Fn or FnMut
let find_fn_kind_from_did = |predicates: &[(ty::Predicate<'tcx>, Span)], substs| {
predicates.iter().find_map(|(pred, _)| {
let pred = if let Some(substs) = substs {
EarlyBinder(*pred).subst(tcx, substs).kind().skip_binder()
} else {
pred.kind().skip_binder()
};
if let ty::PredicateKind::Trait(pred) = pred && pred.self_ty() == ty {
let find_fn_kind_from_did =
|predicates: ty::EarlyBinder<&[(ty::Predicate<'tcx>, Span)]>, substs| {
predicates.0.iter().find_map(|(pred, _)| {
let pred = if let Some(substs) = substs {
predicates.rebind(*pred).subst(tcx, substs).kind().skip_binder()
} else {
pred.kind().skip_binder()
};
if let ty::PredicateKind::Trait(pred) = pred && pred.self_ty() == ty {
if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
return Some(hir::Mutability::Not);
} else if Some(pred.def_id()) == tcx.lang_items().fn_mut_trait() {
return Some(hir::Mutability::Mut);
}
}
None
})
};
None
})
};

// If the type is opaque/param/closure, and it is Fn or FnMut, let's suggest (mutably)
// borrowing the type, since `&mut F: FnMut` iff `F: FnMut` and similarly for `Fn`.
// These types seem reasonably opaque enough that they could be substituted with their
// borrowed variants in a function body when we see a move error.
let borrow_level = match ty.kind() {
ty::Param(_) => find_fn_kind_from_did(
tcx.explicit_predicates_of(self.mir_def_id().to_def_id()).predicates,
tcx.bound_explicit_predicates_of(self.mir_def_id().to_def_id())
.map_bound(|p| p.predicates),
None,
),
ty::Opaque(did, substs) => {
find_fn_kind_from_did(tcx.explicit_item_bounds(*did), Some(*substs))
find_fn_kind_from_did(tcx.bound_explicit_item_bounds(*did), Some(*substs))
}
ty::Closure(_, substs) => match substs.as_closure().kind() {
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/region_name.rs
Original file line number Diff line number Diff line change
@@ -839,7 +839,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
..
}) => (tcx.sess.source_map().end_point(fn_decl_span)),
}) => tcx.sess.source_map().end_point(fn_decl_span),
_ => self.body.span,
};

40 changes: 32 additions & 8 deletions compiler/rustc_builtin_macros/src/format.rs
Original file line number Diff line number Diff line change
@@ -280,6 +280,11 @@ struct Context<'a, 'b> {
unused_names_lint: PositionalNamedArgsLint,
}

pub struct FormatArg {
expr: P<ast::Expr>,
named: bool,
}

/// Parses the arguments from the given list of tokens, returning the diagnostic
/// if there's a parse error so we can continue parsing other format!
/// expressions.
@@ -293,8 +298,8 @@ fn parse_args<'a>(
ecx: &mut ExtCtxt<'a>,
sp: Span,
tts: TokenStream,
) -> PResult<'a, (P<ast::Expr>, Vec<P<ast::Expr>>, FxHashMap<Symbol, (usize, Span)>)> {
let mut args = Vec::<P<ast::Expr>>::new();
) -> PResult<'a, (P<ast::Expr>, Vec<FormatArg>, FxHashMap<Symbol, (usize, Span)>)> {
let mut args = Vec::<FormatArg>::new();
let mut names = FxHashMap::<Symbol, (usize, Span)>::default();

let mut p = ecx.new_parser_from_tts(tts);
@@ -362,7 +367,7 @@ fn parse_args<'a>(
let e = p.parse_expr()?;
if let Some((prev, _)) = names.get(&ident.name) {
ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", ident))
.span_label(args[*prev].span, "previously here")
.span_label(args[*prev].expr.span, "previously here")
.span_label(e.span, "duplicate argument")
.emit();
continue;
@@ -374,7 +379,7 @@ fn parse_args<'a>(
// args. And remember the names.
let slot = args.len();
names.insert(ident.name, (slot, ident.span));
args.push(e);
args.push(FormatArg { expr: e, named: true });
}
_ => {
let e = p.parse_expr()?;
@@ -385,11 +390,11 @@ fn parse_args<'a>(
);
err.span_label(e.span, "positional arguments must be before named arguments");
for pos in names.values() {
err.span_label(args[pos.0].span, "named argument");
err.span_label(args[pos.0].expr.span, "named argument");
}
err.emit();
}
args.push(e);
args.push(FormatArg { expr: e, named: false });
}
}
}
@@ -1214,7 +1219,7 @@ pub fn expand_preparsed_format_args(
ecx: &mut ExtCtxt<'_>,
sp: Span,
efmt: P<ast::Expr>,
args: Vec<P<ast::Expr>>,
args: Vec<FormatArg>,
names: FxHashMap<Symbol, (usize, Span)>,
append_newline: bool,
) -> P<ast::Expr> {
@@ -1304,6 +1309,25 @@ pub fn expand_preparsed_format_args(
e.span_label(fmt_span.from_inner(InnerSpan::new(span.start, span.end)), label);
}
}
if err.should_be_replaced_with_positional_argument {
let captured_arg_span =
fmt_span.from_inner(InnerSpan::new(err.span.start, err.span.end));
let positional_args = args.iter().filter(|arg| !arg.named).collect::<Vec<_>>();
if let Ok(arg) = ecx.source_map().span_to_snippet(captured_arg_span) {
let span = match positional_args.last() {
Some(arg) => arg.expr.span,
None => fmt_sp,
};
e.multipart_suggestion_verbose(
"consider using a positional formatting argument instead",
vec![
(captured_arg_span, positional_args.len().to_string()),
(span.shrink_to_hi(), format!(", {}", arg)),
],
Applicability::MachineApplicable,
);
}
}
e.emit();
return DummyResult::raw_expr(sp, true);
}
@@ -1318,7 +1342,7 @@ pub fn expand_preparsed_format_args(

let mut cx = Context {
ecx,
args,
args: args.into_iter().map(|arg| arg.expr).collect(),
num_captured_args: 0,
arg_types,
arg_unique_types,
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ use rustc_middle::mir::pretty::display_allocation;
use rustc_middle::traits::Reveal;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, subst::Subst, EarlyBinder, TyCtxt};
use rustc_middle::ty::{self, subst::Subst, TyCtxt};
use rustc_span::source_map::Span;
use rustc_target::abi::{self, Abi};
use std::borrow::Cow;
@@ -45,7 +45,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
"Unexpected DefKind: {:?}",
ecx.tcx.def_kind(cid.instance.def_id())
);
let layout = ecx.layout_of(EarlyBinder(body.return_ty()).subst(tcx, cid.instance.substs))?;
let layout = ecx.layout_of(body.bound_return_ty().subst(tcx, cid.instance.substs))?;
assert!(!layout.is_unsized());
let ret = ecx.allocate(layout, MemoryKind::Stack)?;

14 changes: 14 additions & 0 deletions compiler/rustc_lint/src/unused.rs
Original file line number Diff line number Diff line change
@@ -396,6 +396,7 @@ enum UnusedDelimsCtx {
LetScrutineeExpr,
ArrayLenExpr,
AnonConst,
MatchArmExpr,
}

impl From<UnusedDelimsCtx> for &'static str {
@@ -414,6 +415,7 @@ impl From<UnusedDelimsCtx> for &'static str {
UnusedDelimsCtx::BlockRetValue => "block return value",
UnusedDelimsCtx::LetScrutineeExpr => "`let` scrutinee expression",
UnusedDelimsCtx::ArrayLenExpr | UnusedDelimsCtx::AnonConst => "const expression",
UnusedDelimsCtx::MatchArmExpr => "match arm expression",
}
}
}
@@ -805,6 +807,18 @@ impl EarlyLintPass for UnusedParens {
}
return;
}
ExprKind::Match(ref _expr, ref arm) => {
for a in arm {
self.check_unused_delims_expr(
cx,
&a.body,
UnusedDelimsCtx::MatchArmExpr,
false,
None,
None,
);
}
}
_ => {}
}

7 changes: 6 additions & 1 deletion compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Original file line number Diff line number Diff line change
@@ -1311,10 +1311,15 @@ extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
return LLVMBFloatTypeKind;
case Type::X86_AMXTyID:
return LLVMX86_AMXTypeKind;
#if LLVM_VERSION_GE(15, 0)
#if LLVM_VERSION_GE(15, 0) && LLVM_VERSION_LT(16, 0)
case Type::DXILPointerTyID:
report_fatal_error("Rust does not support DirectX typed pointers.");
break;
#endif
#if LLVM_VERSION_GE(16, 0)
case Type::TypedPointerTyID:
report_fatal_error("Rust does not support typed pointers.");
break;
#endif
}
report_fatal_error("Unhandled TypeID.");
6 changes: 6 additions & 0 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
@@ -431,6 +431,12 @@ impl<'tcx> Body<'tcx> {
self.local_decls[RETURN_PLACE].ty
}

/// Returns the return type; it always return first element from `local_decls` array.
#[inline]
pub fn bound_return_ty(&self) -> ty::EarlyBinder<Ty<'tcx>> {
ty::EarlyBinder(self.local_decls[RETURN_PLACE].ty)
}

/// Gets the location of the terminator for the given block.
#[inline]
pub fn terminator_loc(&self, bb: BasicBlock) -> Location {
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/adt.rs
Original file line number Diff line number Diff line change
@@ -563,7 +563,7 @@ impl<'tcx> AdtDef<'tcx> {
///
/// Due to normalization being eager, this applies even if
/// the associated type is behind a pointer (e.g., issue #31299).
pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] {
tcx.adt_sized_constraint(self.did()).0
pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx [Ty<'tcx>]> {
ty::EarlyBinder(tcx.adt_sized_constraint(self.did()).0)
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
@@ -2191,7 +2191,7 @@ impl<'tcx> Ty<'tcx> {

ty::Tuple(tys) => tys.iter().all(|ty| ty.is_trivially_sized(tcx)),

ty::Adt(def, _substs) => def.sized_constraint(tcx).is_empty(),
ty::Adt(def, _substs) => def.sized_constraint(tcx).0.is_empty(),

ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => false,

18 changes: 18 additions & 0 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
@@ -680,6 +680,24 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn bound_const_param_default(self, def_id: DefId) -> ty::EarlyBinder<ty::Const<'tcx>> {
ty::EarlyBinder(self.const_param_default(def_id))
}

pub fn bound_predicates_of(
self,
def_id: DefId,
) -> ty::EarlyBinder<ty::generics::GenericPredicates<'tcx>> {
ty::EarlyBinder(self.predicates_of(def_id))
}

pub fn bound_explicit_predicates_of(
self,
def_id: DefId,
) -> ty::EarlyBinder<ty::generics::GenericPredicates<'tcx>> {
ty::EarlyBinder(self.explicit_predicates_of(def_id))
}

pub fn bound_impl_subject(self, def_id: DefId) -> ty::EarlyBinder<ty::ImplSubject<'tcx>> {
ty::EarlyBinder(self.impl_subject(def_id))
}
}

struct OpaqueTypeExpander<'tcx> {
Original file line number Diff line number Diff line change
@@ -617,7 +617,7 @@ impl SplitVarLenSlice {
// The only admissible fixed-length slice is one of the array size. Whether `max_slice`
// is fixed-length or variable-length, it will be the only relevant slice to output
// here.
Some(_) => (0..0), // empty range
Some(_) => 0..0, // empty range
// We cover all arities in the range `(self.arity..infinity)`. We split that range into
// two: lengths smaller than `max_slice.arity()` are treated independently as
// fixed-lengths slices, and lengths above are captured by `max_slice`.
6 changes: 2 additions & 4 deletions compiler/rustc_mir_transform/src/const_prop.rs
Original file line number Diff line number Diff line change
@@ -18,9 +18,7 @@ use rustc_middle::mir::{
};
use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::subst::{InternalSubsts, Subst};
use rustc_middle::ty::{
self, ConstKind, EarlyBinder, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable,
};
use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable};
use rustc_span::{def_id::DefId, Span};
use rustc_target::abi::{self, HasDataLayout, Size, TargetDataLayout};
use rustc_target::spec::abi::Abi as CallAbi;
@@ -387,7 +385,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
);

let ret_layout = ecx
.layout_of(EarlyBinder(body.return_ty()).subst(tcx, substs))
.layout_of(body.bound_return_ty().subst(tcx, substs))
.ok()
// Don't bother allocating memory for large values.
// I don't know how return types can seem to be unsized but this happens in the
5 changes: 2 additions & 3 deletions compiler/rustc_mir_transform/src/const_prop_lint.rs
Original file line number Diff line number Diff line change
@@ -23,8 +23,7 @@ use rustc_middle::mir::{
use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::subst::{InternalSubsts, Subst};
use rustc_middle::ty::{
self, ConstInt, ConstKind, EarlyBinder, Instance, ParamEnv, ScalarInt, Ty, TyCtxt,
TypeVisitable,
self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitable,
};
use rustc_session::lint;
use rustc_span::Span;
@@ -196,7 +195,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
);

let ret_layout = ecx
.layout_of(EarlyBinder(body.return_ty()).subst(tcx, substs))
.layout_of(body.bound_return_ty().subst(tcx, substs))
.ok()
// Don't bother allocating memory for large values.
// I don't know how return types can seem to be unsized but this happens in the
3 changes: 2 additions & 1 deletion compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -560,7 +560,8 @@ impl<'a> Parser<'a> {
|| (sm.is_multiline(
self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo())
) && t == &token::Pound)
}) {
}) && !expected.contains(&TokenType::Token(token::Comma))
{
// Missing semicolon typo. This is triggered if the next token could either start a
// new statement or is a block close. For example:
//
35 changes: 35 additions & 0 deletions compiler/rustc_parse_format/src/lib.rs
Original file line number Diff line number Diff line change
@@ -175,6 +175,7 @@ pub struct ParseError {
pub label: string::String,
pub span: InnerSpan,
pub secondary_label: Option<(string::String, InnerSpan)>,
pub should_be_replaced_with_positional_argument: bool,
}

/// The parser structure for interpreting the input format string. This is
@@ -236,6 +237,8 @@ impl<'a> Iterator for Parser<'a> {
lbrace_inner_offset.to(InnerOffset(rbrace_inner_offset.0 + 1)),
);
}
} else {
self.suggest_positional_arg_instead_of_captured_arg(arg);
}
Some(NextArgument(arg))
}
@@ -313,6 +316,7 @@ impl<'a> Parser<'a> {
label: label.into(),
span,
secondary_label: None,
should_be_replaced_with_positional_argument: false,
});
}

@@ -336,6 +340,7 @@ impl<'a> Parser<'a> {
label: label.into(),
span,
secondary_label: None,
should_be_replaced_with_positional_argument: false,
});
}

@@ -407,6 +412,7 @@ impl<'a> Parser<'a> {
label,
span: pos.to(pos),
secondary_label,
should_be_replaced_with_positional_argument: false,
});
None
}
@@ -434,6 +440,7 @@ impl<'a> Parser<'a> {
label,
span: pos.to(pos),
secondary_label,
should_be_replaced_with_positional_argument: false,
});
} else {
self.err(description, format!("expected `{:?}`", c), pos.to(pos));
@@ -750,6 +757,34 @@ impl<'a> Parser<'a> {
}
if found { Some(cur) } else { None }
}

fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>) {
if let Some(end) = self.consume_pos('.') {
let byte_pos = self.to_span_index(end);
let start = InnerOffset(byte_pos.0 + 1);
let field = self.argument(start);
// We can only parse `foo.bar` field access, any deeper nesting,
// or another type of expression, like method calls, are not supported
if !self.consume('}') {
return;
}
if let ArgumentNamed(_) = arg.position {
if let ArgumentNamed(_) = field.position {
self.errors.insert(
0,
ParseError {
description: "field access isn't supported".to_string(),
note: None,
label: "not supported".to_string(),
span: InnerSpan::new(arg.position_span.start, field.position_span.end),
secondary_label: None,
should_be_replaced_with_positional_argument: true,
},
);
}
}
}
}
}

/// Finds the indices of all characters that have been processed and differ between the actual
12 changes: 6 additions & 6 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable};
use rustc_middle::ty::{self, EarlyBinder, Term, ToPredicate, Ty, TyCtxt};
use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt};
use rustc_span::symbol::sym;

use std::collections::BTreeMap;
@@ -2005,16 +2005,16 @@ fn confirm_impl_candidate<'cx, 'tcx>(
let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs);
let substs =
translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.defining_node);
let ty = tcx.type_of(assoc_ty.item.def_id);
let ty = tcx.bound_type_of(assoc_ty.item.def_id);
let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst);
let term: ty::Term<'tcx> = if is_const {
let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const {
let identity_substs =
crate::traits::InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id);
let did = ty::WithOptConstParam::unknown(assoc_ty.item.def_id);
let kind = ty::ConstKind::Unevaluated(ty::Unevaluated::new(did, identity_substs));
tcx.mk_const(ty::ConstS { ty, kind }).into()
ty.map_bound(|ty| tcx.mk_const(ty::ConstS { ty, kind }).into())
} else {
ty.into()
ty.map_bound(|ty| ty.into())
};
if substs.len() != tcx.generics_of(assoc_ty.item.def_id).count() {
let err = tcx.ty_error_with_message(
@@ -2024,7 +2024,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
Progress { term: err.into(), obligations: nested }
} else {
assoc_ty_own_obligations(selcx, obligation, &mut nested);
Progress { term: EarlyBinder(term).subst(tcx, substs), obligations: nested }
Progress { term: term.subst(tcx, substs), obligations: nested }
}
}

16 changes: 10 additions & 6 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
@@ -1886,7 +1886,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let sized_crit = def.sized_constraint(self.tcx());
// (*) binder moved here
Where(obligation.predicate.rebind({
sized_crit.iter().map(|ty| EarlyBinder(*ty).subst(self.tcx(), substs)).collect()
sized_crit
.0
.iter()
.map(|ty| sized_crit.rebind(*ty).subst(self.tcx(), substs))
.collect()
}))
}

@@ -2357,11 +2361,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// obligation will normalize to `<$0 as Iterator>::Item = $1` and
// `$1: Copy`, so we must ensure the obligations are emitted in
// that order.
let predicates = tcx.predicates_of(def_id);
let predicates = tcx.bound_predicates_of(def_id);
debug!(?predicates);
assert_eq!(predicates.parent, None);
let mut obligations = Vec::with_capacity(predicates.predicates.len());
for (predicate, span) in predicates.predicates {
assert_eq!(predicates.0.parent, None);
let mut obligations = Vec::with_capacity(predicates.0.predicates.len());
for (predicate, span) in predicates.0.predicates {
let span = *span;
let cause = cause.clone().derived_cause(parent_trait_pred, |derived| {
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
@@ -2375,7 +2379,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
param_env,
cause.clone(),
recursion_depth,
EarlyBinder(*predicate).subst(tcx, substs),
predicates.rebind(*predicate).subst(tcx, substs),
&mut obligations,
);
obligations.push(Obligation { cause, recursion_depth, param_env, predicate });
6 changes: 3 additions & 3 deletions compiler/rustc_trait_selection/src/traits/util.rs
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ use smallvec::SmallVec;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::subst::{GenericArg, Subst, SubstsRef};
use rustc_middle::ty::{self, EarlyBinder, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable};
use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable};

use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext};
pub use rustc_infer::traits::{self, util::*};
@@ -200,8 +200,8 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
impl_def_id: DefId,
impl_substs: SubstsRef<'tcx>,
) -> (ImplSubject<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) {
let subject = selcx.tcx().impl_subject(impl_def_id);
let subject = EarlyBinder(subject).subst(selcx.tcx(), impl_substs);
let subject = selcx.tcx().bound_impl_subject(impl_def_id);
let subject = subject.subst(selcx.tcx(), impl_substs);
let Normalized { value: subject, obligations: normalization_obligations1 } =
super::normalize(selcx, param_env, ObligationCause::dummy(), subject);

31 changes: 16 additions & 15 deletions compiler/rustc_traits/src/chalk/db.rs
Original file line number Diff line number Diff line change
@@ -51,11 +51,11 @@ impl<'tcx> RustIrDatabase<'tcx> {
where
ty::Predicate<'tcx>: LowerInto<'tcx, std::option::Option<T>>,
{
self.interner
.tcx
.explicit_item_bounds(def_id)
let bounds = self.interner.tcx.bound_explicit_item_bounds(def_id);
bounds
.0
.iter()
.map(|(bound, _)| EarlyBinder(*bound).subst(self.interner.tcx, &bound_vars))
.map(|(bound, _)| bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars))
.filter_map(|bound| LowerInto::<Option<_>>::lower_into(bound, self.interner))
.collect()
}
@@ -268,21 +268,20 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t

let where_clauses = self.where_clauses_for(def_id, bound_vars);

let sig = self.interner.tcx.fn_sig(def_id);
let sig = self.interner.tcx.bound_fn_sig(def_id);
let (inputs_and_output, iobinders, _) = crate::chalk::lowering::collect_bound_vars(
self.interner,
self.interner.tcx,
EarlyBinder(sig.inputs_and_output()).subst(self.interner.tcx, bound_vars),
sig.map_bound(|s| s.inputs_and_output()).subst(self.interner.tcx, bound_vars),
);

let argument_types = inputs_and_output[..inputs_and_output.len() - 1]
.iter()
.map(|t| {
EarlyBinder(*t).subst(self.interner.tcx, &bound_vars).lower_into(self.interner)
})
.map(|t| sig.rebind(*t).subst(self.interner.tcx, &bound_vars).lower_into(self.interner))
.collect();

let return_type = EarlyBinder(inputs_and_output[inputs_and_output.len() - 1])
let return_type = sig
.rebind(inputs_and_output[inputs_and_output.len() - 1])
.subst(self.interner.tcx, &bound_vars)
.lower_into(self.interner);

@@ -295,7 +294,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
};
Arc::new(chalk_solve::rust_ir::FnDefDatum {
id: fn_def_id,
sig: sig.lower_into(self.interner),
sig: sig.0.lower_into(self.interner),
binders: chalk_ir::Binders::new(binders, bound),
})
}
@@ -503,12 +502,14 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t

let identity_substs = InternalSubsts::identity_for_item(self.interner.tcx, opaque_ty_id.0);

let explicit_item_bounds = self.interner.tcx.bound_explicit_item_bounds(opaque_ty_id.0);
let bounds =
self.interner
.tcx
.explicit_item_bounds(opaque_ty_id.0)
explicit_item_bounds
.0
.iter()
.map(|(bound, _)| EarlyBinder(*bound).subst(self.interner.tcx, &bound_vars))
.map(|(bound, _)| {
explicit_item_bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars)
})
.map(|bound| {
bound.fold_with(&mut ReplaceOpaqueTyFolder {
tcx: self.interner.tcx,
7 changes: 3 additions & 4 deletions compiler/rustc_ty_utils/src/ty.rs
Original file line number Diff line number Diff line change
@@ -2,9 +2,7 @@ use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{
self, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt,
};
use rustc_middle::ty::{self, Binder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt};
use rustc_trait_selection::traits;

fn sized_constraint_for_ty<'tcx>(
@@ -33,8 +31,9 @@ fn sized_constraint_for_ty<'tcx>(
let adt_tys = adt.sized_constraint(tcx);
debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys);
adt_tys
.0
.iter()
.map(|ty| EarlyBinder(*ty).subst(tcx, substs))
.map(|ty| adt_tys.rebind(*ty).subst(tcx, substs))
.flat_map(|ty| sized_constraint_for_ty(tcx, adtdef, ty))
.collect()
}
13 changes: 7 additions & 6 deletions compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
@@ -15,8 +15,8 @@ use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{
self, AdtKind, DefIdTree, EarlyBinder, GenericParamDefKind, ToPredicate, Ty, TyCtxt,
TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor,
self, AdtKind, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable,
TypeSuperVisitable, TypeVisitable, TypeVisitor,
};
use rustc_session::parse::feature_err;
use rustc_span::symbol::{sym, Ident, Symbol};
@@ -1295,7 +1295,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
let infcx = wfcx.infcx;
let tcx = wfcx.tcx();

let predicates = tcx.predicates_of(def_id);
let predicates = tcx.bound_predicates_of(def_id.to_def_id());
let generics = tcx.generics_of(def_id);

let is_our_default = |def: &ty::GenericParamDef| match def.kind {
@@ -1392,6 +1392,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id

// Now we build the substituted predicates.
let default_obligations = predicates
.0
.predicates
.iter()
.flat_map(|&(pred, sp)| {
@@ -1422,15 +1423,15 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
}
let mut param_count = CountParams::default();
let has_region = pred.visit_with(&mut param_count).is_break();
let substituted_pred = EarlyBinder(pred).subst(tcx, substs);
let substituted_pred = predicates.rebind(pred).subst(tcx, substs);
// Don't check non-defaulted params, dependent defaults (including lifetimes)
// or preds with multiple params.
if substituted_pred.has_param_types_or_consts()
|| param_count.params.len() > 1
|| has_region
{
None
} else if predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) {
} else if predicates.0.predicates.iter().any(|&(p, _)| p == substituted_pred) {
// Avoid duplication of predicates that contain no parameters, for example.
None
} else {
@@ -1456,7 +1457,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
traits::Obligation::new(cause, wfcx.param_env, pred)
});

let predicates = predicates.instantiate_identity(tcx);
let predicates = predicates.0.instantiate_identity(tcx);

let predicates = wfcx.normalize(span, None, predicates);

17 changes: 7 additions & 10 deletions src/ci/scripts/checkout-submodules.sh
Original file line number Diff line number Diff line change
@@ -36,10 +36,7 @@ function fetch_github_commit_archive {
rm $cached
}

# Archive downloads are temporarily disabled due to sudden 504
# gateway timeout errors.
# included="src/llvm-project src/doc/book src/doc/rust-by-example"
included=""
included="src/llvm-project src/doc/book src/doc/rust-by-example"
modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)"
modules=($modules)
use_git=""
@@ -63,9 +60,9 @@ done
retry sh -c "git submodule deinit -f $use_git && \
git submodule sync && \
git submodule update -j 16 --init --recursive --depth 1 $use_git"
# STATUS=0
# for pid in ${bg_pids[*]}
# do
# wait $pid || STATUS=1
# done
# exit ${STATUS}
STATUS=0
for pid in ${bg_pids[*]}
do
wait $pid || STATUS=1
done
exit ${STATUS}
29 changes: 11 additions & 18 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
@@ -956,7 +956,11 @@ fn clean_fn_decl_with_args<'tcx>(
decl: &hir::FnDecl<'tcx>,
args: Arguments,
) -> FnDecl {
FnDecl { inputs: args, output: decl.output.clean(cx), c_variadic: decl.c_variadic }
let output = match decl.output {
hir::FnRetTy::Return(typ) => Return(clean_ty(typ, cx)),
hir::FnRetTy::DefaultReturn(..) => DefaultReturn,
};
FnDecl { inputs: args, output, c_variadic: decl.c_variadic }
}

fn clean_fn_decl_from_did_and_sig<'tcx>(
@@ -991,27 +995,16 @@ fn clean_fn_decl_from_did_and_sig<'tcx>(
}
}

impl<'tcx> Clean<'tcx, FnRetTy> for hir::FnRetTy<'tcx> {
fn clean(&self, cx: &mut DocContext<'tcx>) -> FnRetTy {
match *self {
Self::Return(typ) => Return(clean_ty(typ, cx)),
Self::DefaultReturn(..) => DefaultReturn,
}
}
}

impl<'tcx> Clean<'tcx, Path> for hir::TraitRef<'tcx> {
fn clean(&self, cx: &mut DocContext<'tcx>) -> Path {
let path = clean_path(self.path, cx);
register_res(cx, path.res);
path
}
fn clean_trait_ref<'tcx>(trait_ref: &hir::TraitRef<'tcx>, cx: &mut DocContext<'tcx>) -> Path {
let path = clean_path(trait_ref.path, cx);
register_res(cx, path.res);
path
}

impl<'tcx> Clean<'tcx, PolyTrait> for hir::PolyTraitRef<'tcx> {
fn clean(&self, cx: &mut DocContext<'tcx>) -> PolyTrait {
PolyTrait {
trait_: self.trait_ref.clean(cx),
trait_: clean_trait_ref(&self.trait_ref, cx),
generic_params: self
.bound_generic_params
.iter()
@@ -2000,7 +1993,7 @@ fn clean_impl<'tcx>(
) -> Vec<Item> {
let tcx = cx.tcx;
let mut ret = Vec::new();
let trait_ = impl_.of_trait.as_ref().map(|t| t.clean(cx));
let trait_ = impl_.of_trait.as_ref().map(|t| clean_trait_ref(t, cx));
let items =
impl_.items.iter().map(|ii| tcx.hir().impl_item(ii.id).clean(cx)).collect::<Vec<_>>();
let def_id = tcx.hir().local_def_id(hir_id);
18 changes: 18 additions & 0 deletions src/test/ui/fmt/struct-field-as-captured-argument.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// run-rustfix

#[derive(Debug)]
struct Foo {
field: usize,
}

fn main() {
let foo = Foo { field: 0 };
let bar = 3;
format!("{0}", foo.field); //~ ERROR invalid format string: field access isn't supported
format!("{1} {} {bar}", "aa", foo.field); //~ ERROR invalid format string: field access isn't supported
format!("{2} {} {1} {bar}", "aa", "bb", foo.field); //~ ERROR invalid format string: field access isn't supported
format!("{1} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported
format!("{1:?} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported
format!("{1:#?} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported
format!("{1:.3} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported
}
18 changes: 18 additions & 0 deletions src/test/ui/fmt/struct-field-as-captured-argument.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// run-rustfix

#[derive(Debug)]
struct Foo {
field: usize,
}

fn main() {
let foo = Foo { field: 0 };
let bar = 3;
format!("{foo.field}"); //~ ERROR invalid format string: field access isn't supported
format!("{foo.field} {} {bar}", "aa"); //~ ERROR invalid format string: field access isn't supported
format!("{foo.field} {} {1} {bar}", "aa", "bb"); //~ ERROR invalid format string: field access isn't supported
format!("{foo.field} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported
format!("{foo.field:?} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported
format!("{foo.field:#?} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported
format!("{foo.field:.3} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported
}
79 changes: 79 additions & 0 deletions src/test/ui/fmt/struct-field-as-captured-argument.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
error: invalid format string: field access isn't supported
--> $DIR/struct-field-as-captured-argument.rs:11:15
|
LL | format!("{foo.field}");
| ^^^^^^^^^ not supported in format string
|
help: consider using a positional formatting argument instead
|
LL | format!("{0}", foo.field);
| ~ +++++++++++

error: invalid format string: field access isn't supported
--> $DIR/struct-field-as-captured-argument.rs:12:15
|
LL | format!("{foo.field} {} {bar}", "aa");
| ^^^^^^^^^ not supported in format string
|
help: consider using a positional formatting argument instead
|
LL | format!("{1} {} {bar}", "aa", foo.field);
| ~ +++++++++++

error: invalid format string: field access isn't supported
--> $DIR/struct-field-as-captured-argument.rs:13:15
|
LL | format!("{foo.field} {} {1} {bar}", "aa", "bb");
| ^^^^^^^^^ not supported in format string
|
help: consider using a positional formatting argument instead
|
LL | format!("{2} {} {1} {bar}", "aa", "bb", foo.field);
| ~ +++++++++++

error: invalid format string: field access isn't supported
--> $DIR/struct-field-as-captured-argument.rs:14:15
|
LL | format!("{foo.field} {} {baz}", "aa", baz = 3);
| ^^^^^^^^^ not supported in format string
|
help: consider using a positional formatting argument instead
|
LL | format!("{1} {} {baz}", "aa", foo.field, baz = 3);
| ~ +++++++++++

error: invalid format string: field access isn't supported
--> $DIR/struct-field-as-captured-argument.rs:15:15
|
LL | format!("{foo.field:?} {} {baz}", "aa", baz = 3);
| ^^^^^^^^^ not supported in format string
|
help: consider using a positional formatting argument instead
|
LL | format!("{1:?} {} {baz}", "aa", foo.field, baz = 3);
| ~ +++++++++++

error: invalid format string: field access isn't supported
--> $DIR/struct-field-as-captured-argument.rs:16:15
|
LL | format!("{foo.field:#?} {} {baz}", "aa", baz = 3);
| ^^^^^^^^^ not supported in format string
|
help: consider using a positional formatting argument instead
|
LL | format!("{1:#?} {} {baz}", "aa", foo.field, baz = 3);
| ~ +++++++++++

error: invalid format string: field access isn't supported
--> $DIR/struct-field-as-captured-argument.rs:17:15
|
LL | format!("{foo.field:.3} {} {baz}", "aa", baz = 3);
| ^^^^^^^^^ not supported in format string
|
help: consider using a positional formatting argument instead
|
LL | format!("{1:.3} {} {baz}", "aa", foo.field, baz = 3);
| ~ +++++++++++

error: aborting due to 7 previous errors

9 changes: 9 additions & 0 deletions src/test/ui/lint/unused/issue-92751.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#[deny(unused)]
pub fn broken(x: Option<()>) -> i32 {
match x {
Some(()) => (1), //~ ERROR unnecessary parentheses around match arm expression
None => (2), //~ ERROR unnecessary parentheses around match arm expression
}
}

fn main() { }
32 changes: 32 additions & 0 deletions src/test/ui/lint/unused/issue-92751.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
error: unnecessary parentheses around match arm expression
--> $DIR/issue-92751.rs:4:21
|
LL | Some(()) => (1),
| ^ ^
|
note: the lint level is defined here
--> $DIR/issue-92751.rs:1:8
|
LL | #[deny(unused)]
| ^^^^^^
= note: `#[deny(unused_parens)]` implied by `#[deny(unused)]`
help: remove these parentheses
|
LL - Some(()) => (1),
LL + Some(()) => 1,
|

error: unnecessary parentheses around match arm expression
--> $DIR/issue-92751.rs:5:17
|
LL | None => (2),
| ^ ^
|
help: remove these parentheses
|
LL - None => (2),
LL + None => 2,
|

error: aborting due to 2 previous errors

2 changes: 1 addition & 1 deletion src/test/ui/parser/issues/issue-88770.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
// error-pattern:this file contains an unclosed delimiter
// error-pattern:expected one of
// error-pattern:missing `in` in `for` loop
// error-pattern:expected `;`, found `e`
// error-pattern:expected one of `!`, `)`, `,`, `.`, `::`, `;`, `?`, `{`, or an operator, found `e`

fn m(){print!("",(c for&g
u
16 changes: 5 additions & 11 deletions src/test/ui/parser/issues/issue-88770.stderr
Original file line number Diff line number Diff line change
@@ -48,19 +48,13 @@ error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found
LL | fn m(){print!("",(c for&g
| ^^^ expected one of 8 possible tokens

error: expected `;`, found `e`
--> $DIR/issue-88770.rs:10:2
error: expected one of `!`, `)`, `,`, `.`, `::`, `;`, `?`, `{`, or an operator, found `e`
--> $DIR/issue-88770.rs:11:1
|
LL | e
| ^ help: add `;` here
| - expected one of 9 possible tokens
LL | e
| - unexpected token
| ^ unexpected token

error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `)`
--> $DIR/issue-88770.rs:11:3
|
LL | e
| ^ expected one of 7 possible tokens

error: aborting due to 7 previous errors
error: aborting due to 6 previous errors

5 changes: 5 additions & 0 deletions src/test/ui/parser/suggest-semi-in-array.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fn main() {
let v = [1
2];
//~^ ERROR expected one of `,`, `.`, `;`, `?`, `]`, or an operator, found `2`
}
10 changes: 10 additions & 0 deletions src/test/ui/parser/suggest-semi-in-array.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: expected one of `,`, `.`, `;`, `?`, `]`, or an operator, found `2`
--> $DIR/suggest-semi-in-array.rs:3:5
|
LL | let v = [1
| - expected one of `,`, `.`, `;`, `?`, `]`, or an operator
LL | 2];
| ^ unexpected token

error: aborting due to previous error