From 2808e071dd5042e839749f9d5f794dc0896d1bfd Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 8 Aug 2022 15:41:32 +0200 Subject: [PATCH 1/8] Simplify format_args builtin macro implementation. Instead of a FxHashMap for the named arguments, this now includes the name and span in the elements of the Vec directly. The FxHashMap still exists to look up the index, but no longer contains the span. Looking up the name or span of an argument is now trivial and does not need the map anymore. --- compiler/rustc_builtin_macros/src/format.rs | 150 +++++++++----------- 1 file changed, 64 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 9eb96ec76800c..d96f24c7bc715 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -130,64 +130,46 @@ impl PositionalNamedArgsLint { /// CountIsParam, which contains an index into the arguments. fn maybe_add_positional_named_arg( &mut self, - current_positional_arg: usize, - total_args_length: usize, - format_argument_index: usize, + arg: Option<&FormatArg>, ty: PositionalNamedArgType, cur_piece: usize, inner_span_to_replace: Option, - names: &FxHashMap, has_formatting: bool, ) { - let start_of_named_args = total_args_length - names.len(); - if current_positional_arg >= start_of_named_args { - self.maybe_push( - format_argument_index, - ty, - cur_piece, - inner_span_to_replace, - names, - has_formatting, - ) + if let Some(arg) = arg { + if let Some(name) = arg.name { + self.push(name, ty, cur_piece, inner_span_to_replace, has_formatting) + } } } - /// Try constructing a PositionalNamedArg struct and pushing it into the vec of positional - /// named arguments. If a named arg associated with `format_argument_index` cannot be found, - /// a new item will not be added as the lint cannot be emitted in this case. - fn maybe_push( + /// Construct a PositionalNamedArg struct and push it into the vec of positional + /// named arguments. + fn push( &mut self, - format_argument_index: usize, + arg_name: Ident, ty: PositionalNamedArgType, cur_piece: usize, inner_span_to_replace: Option, - names: &FxHashMap, has_formatting: bool, ) { - let named_arg = names - .iter() - .find(|&(_, &(index, _))| index == format_argument_index) - .map(|found| found.clone()); - - if let Some((&replacement, &(_, positional_named_arg_span))) = named_arg { - // In FormatSpec, `precision_span` starts at the leading `.`, which we want to keep in - // the lint suggestion, so increment `start` by 1 when `PositionalArgumentType` is - // `Precision`. - let inner_span_to_replace = if ty == PositionalNamedArgType::Precision { - inner_span_to_replace - .map(|is| rustc_parse_format::InnerSpan { start: is.start + 1, end: is.end }) - } else { - inner_span_to_replace - }; - self.positional_named_args.push(PositionalNamedArg { - ty, - cur_piece, - inner_span_to_replace, - replacement, - positional_named_arg_span, - has_formatting, - }); - } + // In FormatSpec, `precision_span` starts at the leading `.`, which we want to keep in + // the lint suggestion, so increment `start` by 1 when `PositionalArgumentType` is + // `Precision`. + let inner_span_to_replace = if ty == PositionalNamedArgType::Precision { + inner_span_to_replace + .map(|is| rustc_parse_format::InnerSpan { start: is.start + 1, end: is.end }) + } else { + inner_span_to_replace + }; + self.positional_named_args.push(PositionalNamedArg { + ty, + cur_piece, + inner_span_to_replace, + replacement: arg_name.name, + positional_named_arg_span: arg_name.span, + has_formatting, + }); } } @@ -211,7 +193,7 @@ struct Context<'a, 'b> { /// * `arg_types` (in JSON): `[[0, 1, 0], [0, 1, 1], [0, 1]]` /// * `arg_unique_types` (in simplified JSON): `[["o", "x"], ["o", "x"], ["o", "x"]]` /// * `names` (in JSON): `{"foo": 2}` - args: Vec>, + args: Vec, /// The number of arguments that were added by implicit capturing. num_captured_args: usize, /// Placeholder slot numbers indexed by argument. @@ -219,7 +201,7 @@ struct Context<'a, 'b> { /// Unique format specs seen for each argument. arg_unique_types: Vec>, /// Map from named arguments to their resolved indices. - names: FxHashMap, + names: FxHashMap, /// The latest consecutive literal strings, or empty if there weren't any. literal: String, @@ -282,7 +264,7 @@ struct Context<'a, 'b> { pub struct FormatArg { expr: P, - named: bool, + name: Option, } /// Parses the arguments from the given list of tokens, returning the diagnostic @@ -298,9 +280,9 @@ fn parse_args<'a>( ecx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream, -) -> PResult<'a, (P, Vec, FxHashMap)> { +) -> PResult<'a, (P, Vec, FxHashMap)> { let mut args = Vec::::new(); - let mut names = FxHashMap::::default(); + let mut names = FxHashMap::::default(); let mut p = ecx.new_parser_from_tts(tts); @@ -365,9 +347,9 @@ fn parse_args<'a>( p.bump(); p.expect(&token::Eq)?; let e = p.parse_expr()?; - if let Some((prev, _)) = names.get(&ident.name) { + if let Some(&prev) = names.get(&ident.name) { ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", ident)) - .span_label(args[*prev].expr.span, "previously here") + .span_label(args[prev].expr.span, "previously here") .span_label(e.span, "duplicate argument") .emit(); continue; @@ -378,8 +360,8 @@ fn parse_args<'a>( // if the input is valid, we can simply append to the positional // args. And remember the names. let slot = args.len(); - names.insert(ident.name, (slot, ident.span)); - args.push(FormatArg { expr: e, named: true }); + names.insert(ident.name, slot); + args.push(FormatArg { expr: e, name: Some(ident) }); } _ => { let e = p.parse_expr()?; @@ -389,12 +371,12 @@ fn parse_args<'a>( "positional arguments cannot follow named arguments", ); err.span_label(e.span, "positional arguments must be before named arguments"); - for pos in names.values() { - err.span_label(args[pos.0].expr.span, "named argument"); + for &pos in names.values() { + err.span_label(args[pos].expr.span, "named argument"); } err.emit(); } - args.push(FormatArg { expr: e, named: false }); + args.push(FormatArg { expr: e, name: None }); } } } @@ -410,8 +392,7 @@ impl<'a, 'b> Context<'a, 'b> { fn resolve_name_inplace(&mut self, p: &mut parse::Piece<'_>) { // NOTE: the `unwrap_or` branch is needed in case of invalid format // arguments, e.g., `format_args!("{foo}")`. - let lookup = - |s: &str| self.names.get(&Symbol::intern(s)).unwrap_or(&(0, Span::default())).0; + let lookup = |s: &str| self.names.get(&Symbol::intern(s)).copied().unwrap_or(0); match *p { parse::String(_) => {} @@ -457,13 +438,10 @@ impl<'a, 'b> Context<'a, 'b> { let pos = match arg.position { parse::ArgumentIs(i) => { self.unused_names_lint.maybe_add_positional_named_arg( - i, - self.args.len(), - i, + self.args.get(i), PositionalNamedArgType::Arg, self.curpiece, Some(arg.position_span), - &self.names, has_precision || has_width, ); @@ -471,13 +449,10 @@ impl<'a, 'b> Context<'a, 'b> { } parse::ArgumentImplicitlyIs(i) => { self.unused_names_lint.maybe_add_positional_named_arg( - i, - self.args.len(), - i, + self.args.get(i), PositionalNamedArgType::Arg, self.curpiece, None, - &self.names, has_precision || has_width, ); Exact(i) @@ -563,13 +538,10 @@ impl<'a, 'b> Context<'a, 'b> { parse::CountImplied | parse::CountIs(..) => {} parse::CountIsParam(i) => { self.unused_names_lint.maybe_add_positional_named_arg( - i, - self.args.len(), - i, + self.args.get(i), named_arg_type, self.curpiece, *inner_span, - &self.names, true, ); self.verify_arg_type(Exact(i), Count); @@ -622,7 +594,7 @@ impl<'a, 'b> Context<'a, 'b> { ); for arg in &self.args { // Point at the arguments that will be formatted. - e.span_label(arg.span, ""); + e.span_label(arg.expr.span, ""); } } else { let (mut refs, spans): (Vec<_>, Vec<_>) = refs.unzip(); @@ -692,7 +664,7 @@ impl<'a, 'b> Context<'a, 'b> { ); if let Some(arg) = self.args.get(pos) { e.span_label( - arg.span, + arg.expr.span, "this parameter corresponds to the precision flag", ); } @@ -771,7 +743,7 @@ impl<'a, 'b> Context<'a, 'b> { match self.names.get(&name) { Some(&idx) => { // Treat as positional arg. - self.verify_arg_type(Capture(idx.0), ty) + self.verify_arg_type(Capture(idx), ty) } None => { // For the moment capturing variables from format strings expanded from macros is @@ -787,8 +759,11 @@ impl<'a, 'b> Context<'a, 'b> { self.fmtsp }; self.num_captured_args += 1; - self.args.push(self.ecx.expr_ident(span, Ident::new(name, span))); - self.names.insert(name, (idx, span)); + self.args.push(FormatArg { + expr: self.ecx.expr_ident(span, Ident::new(name, span)), + name: Some(Ident::new(name, span)), + }); + self.names.insert(name, idx); self.verify_arg_type(Capture(idx), ty) } else { let msg = format!("there is no argument named `{}`", name); @@ -1054,11 +1029,11 @@ impl<'a, 'b> Context<'a, 'b> { // evaluated a single time each, in the order written by the programmer, // and that the surrounding future/generator (if any) is Send whenever // possible. - let no_need_for_match = - nicely_ordered && !original_args.iter().skip(1).any(|e| may_contain_yield_point(e)); + let no_need_for_match = nicely_ordered + && !original_args.iter().skip(1).any(|arg| may_contain_yield_point(&arg.expr)); for (arg_index, arg_ty) in fmt_arg_index_and_ty { - let e = &mut original_args[arg_index]; + let e = &mut original_args[arg_index].expr; let span = e.span; let arg = if no_need_for_match { let expansion_span = e.span.with_ctxt(self.macsp.ctxt()); @@ -1087,7 +1062,9 @@ impl<'a, 'b> Context<'a, 'b> { // span is otherwise unavailable in the MIR used by borrowck). let heads = original_args .into_iter() - .map(|e| self.ecx.expr_addr_of(e.span.with_ctxt(self.macsp.ctxt()), e)) + .map(|arg| { + self.ecx.expr_addr_of(arg.expr.span.with_ctxt(self.macsp.ctxt()), arg.expr) + }) .collect(); let pat = self.ecx.pat_ident(self.macsp, Ident::new(sym::args, self.macsp)); @@ -1220,7 +1197,7 @@ pub fn expand_preparsed_format_args( sp: Span, efmt: P, args: Vec, - names: FxHashMap, + names: FxHashMap, append_newline: bool, ) -> P { // NOTE: this verbose way of initializing `Vec>` is because @@ -1312,16 +1289,17 @@ pub fn expand_preparsed_format_args( 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::>(); + let n_positional_args = + args.iter().rposition(|arg| arg.name.is_none()).map_or(0, |i| i + 1); if let Ok(arg) = ecx.source_map().span_to_snippet(captured_arg_span) { - let span = match positional_args.last() { + let span = match args[..n_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()), + (captured_arg_span, n_positional_args.to_string()), (span.shrink_to_hi(), format!(", {}", arg)), ], Applicability::MachineApplicable, @@ -1338,11 +1316,11 @@ pub fn expand_preparsed_format_args( .map(|span| fmt_span.from_inner(InnerSpan::new(span.start, span.end))) .collect(); - let named_pos: FxHashSet = names.values().cloned().map(|(i, _)| i).collect(); + let named_pos: FxHashSet = names.values().cloned().collect(); let mut cx = Context { ecx, - args: args.into_iter().map(|arg| arg.expr).collect(), + args, num_captured_args: 0, arg_types, arg_unique_types, @@ -1417,7 +1395,7 @@ pub fn expand_preparsed_format_args( // positional argument "argument never used" }; - (cx.args[i].span, msg) + (cx.args[i].expr.span, msg) }) .collect::>(); From a639fdb7d89e7acb8ca3e158ecf72c27ad525518 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 8 Aug 2022 15:51:14 +0200 Subject: [PATCH 2/8] Get rid of named_pos in format_args impl. --- compiler/rustc_builtin_macros/src/format.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index d96f24c7bc715..53c13873b1016 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -1316,8 +1316,6 @@ pub fn expand_preparsed_format_args( .map(|span| fmt_span.from_inner(InnerSpan::new(span.start, span.end))) .collect(); - let named_pos: FxHashSet = names.values().cloned().collect(); - let mut cx = Context { ecx, args, @@ -1388,11 +1386,9 @@ pub fn expand_preparsed_format_args( .enumerate() .filter(|(i, ty)| ty.is_empty() && !cx.count_positions.contains_key(&i)) .map(|(i, _)| { - let msg = if named_pos.contains(&i) { - // named argument + let msg = if cx.args[i].name.is_some() { "named argument never used" } else { - // positional argument "argument never used" }; (cx.args[i].expr.span, msg) From d3fee8dbf311aa916d98912261c16cad1a27b53f Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 6 Aug 2022 23:43:33 +0200 Subject: [PATCH 3/8] Refuse to codegen an upstream static. --- compiler/rustc_monomorphize/src/collector.rs | 5 +++++ .../run-make/issue-85401-static-mir/Makefile | 16 ++++++++++++++++ src/test/run-make/issue-85401-static-mir/bar.rs | 4 ++++ src/test/run-make/issue-85401-static-mir/baz.rs | 3 +++ src/test/run-make/issue-85401-static-mir/foo.rs | 5 +++++ 5 files changed, 33 insertions(+) create mode 100644 src/test/run-make/issue-85401-static-mir/Makefile create mode 100644 src/test/run-make/issue-85401-static-mir/bar.rs create mode 100644 src/test/run-make/issue-85401-static-mir/baz.rs create mode 100644 src/test/run-make/issue-85401-static-mir/foo.rs diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 68b65658c72b5..96bbf5802e738 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1027,6 +1027,11 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> return false; } + if let DefKind::Static(_) = tcx.def_kind(def_id) { + // We cannot monomorphize statics from upstream crates. + return false; + } + if !tcx.is_mir_available(def_id) { bug!("no MIR available for {:?}", def_id); } diff --git a/src/test/run-make/issue-85401-static-mir/Makefile b/src/test/run-make/issue-85401-static-mir/Makefile new file mode 100644 index 0000000000000..5e094cb4d3379 --- /dev/null +++ b/src/test/run-make/issue-85401-static-mir/Makefile @@ -0,0 +1,16 @@ +-include ../../run-make-fulldeps/tools.mk + +# Regression test for issue #85401 +# Verify that we do not ICE when trying to access MIR for statics, +# but emit an error when linking. + +OUTPUT_FILE := $(TMPDIR)/build-output + +all: + $(RUSTC) --crate-type rlib --crate-name foo -Crelocation-model=pic --edition=2018 foo.rs -Zalways-encode-mir=yes --emit metadata -o $(TMPDIR)/libfoo.rmeta + $(RUSTC) --crate-type rlib --crate-name bar -Crelocation-model=pic --edition=2018 bar.rs -o $(TMPDIR)/libbar.rlib --extern=foo=$(TMPDIR)/libfoo.rmeta + $(RUSTC) --crate-type bin --crate-name baz -Crelocation-model=pic --edition=2018 baz.rs -o $(TMPDIR)/baz -L $(TMPDIR) --extern=bar=$(TMPDIR)/libbar.rlib > $(OUTPUT_FILE) 2>&1; [ $$? -eq 1 ] + cat $(OUTPUT_FILE) + $(CGREP) 'crate `foo` required to be available in rlib format, but was not found in this form' < $(OUTPUT_FILE) + # -v tests are fragile, hopefully this text won't change + $(CGREP) -v "internal compiler error" < $(OUTPUT_FILE) diff --git a/src/test/run-make/issue-85401-static-mir/bar.rs b/src/test/run-make/issue-85401-static-mir/bar.rs new file mode 100644 index 0000000000000..15b12ecf36ff0 --- /dev/null +++ b/src/test/run-make/issue-85401-static-mir/bar.rs @@ -0,0 +1,4 @@ +pub fn bar() { + println!("bar {}", foo::FOO); + foo::foo(); +} diff --git a/src/test/run-make/issue-85401-static-mir/baz.rs b/src/test/run-make/issue-85401-static-mir/baz.rs new file mode 100644 index 0000000000000..2ff4c51e5d278 --- /dev/null +++ b/src/test/run-make/issue-85401-static-mir/baz.rs @@ -0,0 +1,3 @@ +fn main() { + bar::bar() +} diff --git a/src/test/run-make/issue-85401-static-mir/foo.rs b/src/test/run-make/issue-85401-static-mir/foo.rs new file mode 100644 index 0000000000000..d064c454600ac --- /dev/null +++ b/src/test/run-make/issue-85401-static-mir/foo.rs @@ -0,0 +1,5 @@ +pub static FOO: &str = "foo"; + +pub fn foo() { + println!("foo"); +} From 1137fffe28899e992dc43b1152ea7daaa9ab3424 Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 13 Aug 2022 19:57:22 +0200 Subject: [PATCH 4/8] change `InlineAsmCtxt` to not talk about `FnCtxt` --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 12 +++- .../rustc_typeck/src/check/intrinsicck.rs | 67 ++++++++++--------- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 1d1f755947fdc..8f0d9dd71a850 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -58,7 +58,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len()); for (asm, hir_id) in deferred_asm_checks.drain(..) { let enclosing_id = self.tcx.hir().enclosing_body_owner(hir_id); - InlineAsmCtxt::new_in_fn(self) + let get_operand_ty = |expr| { + let ty = self.typeck_results.borrow().expr_ty_adjusted(expr); + let ty = self.resolve_vars_if_possible(ty); + if ty.has_infer_types_or_consts() { + assert!(self.is_tainted_by_errors()); + self.tcx.ty_error() + } else { + self.tcx.erase_regions(ty) + } + }; + InlineAsmCtxt::new_in_fn(self.tcx, self.param_env, get_operand_ty) .check_asm(asm, self.tcx.hir().local_def_id_to_hir_id(enclosing_id)); } } diff --git a/compiler/rustc_typeck/src/check/intrinsicck.rs b/compiler/rustc_typeck/src/check/intrinsicck.rs index df94abbafb1bd..721ebba651477 100644 --- a/compiler/rustc_typeck/src/check/intrinsicck.rs +++ b/compiler/rustc_typeck/src/check/intrinsicck.rs @@ -9,7 +9,6 @@ use rustc_session::lint; use rustc_span::{Span, Symbol, DUMMY_SP}; use rustc_target::abi::{Pointer, VariantIdx}; use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType}; -use rustc_trait_selection::infer::InferCtxtExt; use super::FnCtxt; @@ -98,12 +97,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } err.emit(); } +} + +pub struct InlineAsmCtxt<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + get_operand_ty: Box) -> Ty<'tcx> + 'a>, +} + +impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { + pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self { + InlineAsmCtxt { + tcx, + param_env: ty::ParamEnv::empty(), + get_operand_ty: Box::new(|e| bug!("asm operand in global asm: {e:?}")), + } + } + + pub fn new_in_fn( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + get_operand_ty: impl Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a, + ) -> Self { + InlineAsmCtxt { tcx, param_env, get_operand_ty: Box::new(get_operand_ty) } + } // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()` fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool { // Type still may have region variables, but `Sized` does not depend // on those, so just erase them before querying. - if self.tcx.erase_regions(ty).is_sized(self.tcx.at(DUMMY_SP), self.param_env) { + if ty.is_sized(self.tcx.at(DUMMY_SP), self.param_env) { return true; } if let ty::Foreign(..) = ty.kind() { @@ -111,36 +134,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } false } -} - -pub struct InlineAsmCtxt<'a, 'tcx> { - tcx: TyCtxt<'tcx>, - fcx: Option<&'a FnCtxt<'a, 'tcx>>, -} - -impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { - pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self { - InlineAsmCtxt { tcx, fcx: None } - } - - pub fn new_in_fn(fcx: &'a FnCtxt<'a, 'tcx>) -> Self { - InlineAsmCtxt { tcx: fcx.tcx, fcx: Some(fcx) } - } fn check_asm_operand_type( &self, idx: usize, reg: InlineAsmRegOrRegClass, - expr: &hir::Expr<'tcx>, + expr: &'tcx hir::Expr<'tcx>, template: &[InlineAsmTemplatePiece], is_input: bool, - tied_input: Option<(&hir::Expr<'tcx>, Option)>, + tied_input: Option<(&'tcx hir::Expr<'tcx>, Option)>, target_features: &FxHashSet, ) -> Option { - let fcx = self.fcx.unwrap_or_else(|| span_bug!(expr.span, "asm operand for global asm")); - // Check the type against the allowed types for inline asm. - let ty = fcx.typeck_results.borrow().expr_ty_adjusted(expr); - let ty = fcx.resolve_vars_if_possible(ty); + let ty = (self.get_operand_ty)(expr); + if ty.has_infer_types_or_consts() { + bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty); + } let asm_ty_isize = match self.tcx.sess.target.pointer_width { 16 => InlineAsmType::I16, 32 => InlineAsmType::I32, @@ -148,12 +156,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { _ => unreachable!(), }; - // Expect types to be fully resolved, no const or type variables. - if ty.has_infer_types_or_consts() { - assert!(fcx.is_tainted_by_errors()); - return None; - } - let asm_ty = match *ty.kind() { // `!` is allowed for input but not for output (issue #87802) ty::Never if is_input => return None, @@ -167,7 +169,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Float(FloatTy::F32) => Some(InlineAsmType::F32), ty::Float(FloatTy::F64) => Some(InlineAsmType::F64), ty::FnPtr(_) => Some(asm_ty_isize), - ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if fcx.is_thin_ptr_ty(ty) => { + ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if self.is_thin_ptr_ty(ty) => { Some(asm_ty_isize) } ty::Adt(adt, substs) if adt.repr().simd() => { @@ -219,7 +221,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // Check that the type implements Copy. The only case where this can // possibly fail is for SIMD types which don't #[derive(Copy)]. - if !fcx.infcx.type_is_copy_modulo_regions(fcx.param_env, ty, DUMMY_SP) { + if !ty.is_copy_modulo_regions(self.tcx.at(expr.span), self.param_env) { let msg = "arguments for inline assembly must be copyable"; let mut err = self.tcx.sess.struct_span_err(expr.span, msg); err.note(&format!("`{ty}` does not implement the Copy trait")); @@ -240,8 +242,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { let msg = "incompatible types for asm inout argument"; let mut err = self.tcx.sess.struct_span_err(vec![in_expr.span, expr.span], msg); - let in_expr_ty = fcx.typeck_results.borrow().expr_ty_adjusted(in_expr); - let in_expr_ty = fcx.resolve_vars_if_possible(in_expr_ty); + let in_expr_ty = (self.get_operand_ty)(in_expr); err.span_label(in_expr.span, &format!("type `{in_expr_ty}`")); err.span_label(expr.span, &format!("type `{ty}`")); err.note( From 44f878d75f0d1d37cec965e628faf99b18826ad8 Mon Sep 17 00:00:00 2001 From: Rageking8 <106309953+Rageking8@users.noreply.github.com> Date: Sun, 14 Aug 2022 22:17:49 +0800 Subject: [PATCH 5/8] Make code slightly more uniform --- compiler/rustc_parse/src/parser/diagnostics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index f4c6b33a52924..018f0ad71efc9 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -590,7 +590,7 @@ impl<'a> Parser<'a> { ) } else if expected.is_empty() { ( - format!("unexpected token: {}", actual), + format!("unexpected token: {actual}"), (self.prev_token.span, "unexpected token after this".to_string()), ) } else { @@ -1497,7 +1497,7 @@ impl<'a> Parser<'a> { MultiSugg { msg: format!("use `{}= 1` instead", kind.op.chr()), patches: vec![ - (pre_span, format!("{{ let {} = ", tmp_var)), + (pre_span, format!("{{ let {tmp_var} = ")), (post_span, format!("; {} {}= 1; {} }}", base_src, kind.op.chr(), tmp_var)), ], applicability: Applicability::HasPlaceholders, From 16b33cc1e32d1814d961d97a6e76defc079316d2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 13 Aug 2022 07:09:08 +0000 Subject: [PATCH 6/8] Point to argument if it's self type of unsatisfied projection predicate --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 13 +-- ...nding-to-type-defined-in-supertrait.stderr | 12 ++- .../associated-types-eq-3.stderr | 10 ++- .../associated-types-issue-20346.stderr | 6 +- ...ated-types-multiple-types-one-trait.stderr | 12 ++- .../ui/associated-types/issue-87261.stderr | 84 ++++++++++++------- src/test/ui/error-codes/E0271.stderr | 6 +- .../issue-74684-2.stderr | 6 +- .../issue-62203-hrtb-ice.rs | 2 +- .../issue-62203-hrtb-ice.stderr | 21 +++-- .../intrinsics/const-eval-select-bad.stderr | 6 +- .../check-trait-object-bounds-5.stderr | 6 +- .../check-trait-object-bounds-6.stderr | 6 +- 13 files changed, 125 insertions(+), 65 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index a7df5320296cd..1f2dfc30ae03b 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1660,12 +1660,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ObligationCauseCode::ImplDerivedObligation(code) => { code.derived.parent_trait_pred.self_ty().skip_binder().into() } - _ if let ty::PredicateKind::Trait(predicate) = - error.obligation.predicate.kind().skip_binder() => - { - predicate.self_ty().into() - } - _ => continue, + _ => match error.obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Trait(predicate) => predicate.self_ty().into(), + ty::PredicateKind::Projection(predicate) => { + predicate.projection_ty.self_ty().into() + } + _ => continue, + }, }; let self_ = self.resolve_vars_if_possible(self_); let ty_matches_self = |ty: Ty<'tcx>| ty.walk().any(|arg| arg == self_); diff --git a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr index 0cccc6b38a3a9..a777e064f1a0a 100644 --- a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr +++ b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr @@ -1,8 +1,10 @@ error[E0271]: type mismatch resolving `::Color == Blue` - --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:10 + --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:19 | LL | fn b() { blue_car(ModelT); } - | ^^^^^^^^ type mismatch resolving `::Color == Blue` + | -------- ^^^^^^ type mismatch resolving `::Color == Blue` + | | + | required by a bound introduced by this call | note: expected this to be `Blue` --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:16:40 @@ -16,10 +18,12 @@ LL | fn blue_car>(c: C) { | ^^^^^^^^^^ required by this bound in `blue_car` error[E0271]: type mismatch resolving `::Color == Black` - --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:10 + --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:20 | LL | fn c() { black_car(ModelU); } - | ^^^^^^^^^ type mismatch resolving `::Color == Black` + | --------- ^^^^^^ type mismatch resolving `::Color == Black` + | | + | required by a bound introduced by this call | note: expected this to be `Black` --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:21:40 diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr index bed63a5e6df03..19750fe1f333f 100644 --- a/src/test/ui/associated-types/associated-types-eq-3.stderr +++ b/src/test/ui/associated-types/associated-types-eq-3.stderr @@ -14,10 +14,12 @@ LL | fn foo2>(x: I) { | +++++++++ error[E0271]: type mismatch resolving `::A == Bar` - --> $DIR/associated-types-eq-3.rs:38:5 + --> $DIR/associated-types-eq-3.rs:38:10 | LL | foo1(a); - | ^^^^ type mismatch resolving `::A == Bar` + | ---- ^ type mismatch resolving `::A == Bar` + | | + | required by a bound introduced by this call | note: expected this to be `Bar` --> $DIR/associated-types-eq-3.rs:12:14 @@ -34,7 +36,9 @@ error[E0271]: type mismatch resolving `::A == Bar` --> $DIR/associated-types-eq-3.rs:40:9 | LL | baz(&a); - | ^^ type mismatch resolving `::A == Bar` + | --- ^^ type mismatch resolving `::A == Bar` + | | + | required by a bound introduced by this call | note: expected this to be `Bar` --> $DIR/associated-types-eq-3.rs:12:14 diff --git a/src/test/ui/associated-types/associated-types-issue-20346.stderr b/src/test/ui/associated-types/associated-types-issue-20346.stderr index a67cf99283cfa..b1708b96e5254 100644 --- a/src/test/ui/associated-types/associated-types-issue-20346.stderr +++ b/src/test/ui/associated-types/associated-types-issue-20346.stderr @@ -1,11 +1,13 @@ error[E0271]: type mismatch resolving ` as Iterator>::Item == Option` - --> $DIR/associated-types-issue-20346.rs:34:5 + --> $DIR/associated-types-issue-20346.rs:34:36 | LL | fn test_adapter>>(it: I) { | - this type parameter ... LL | is_iterator_of::, _>(&adapter); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving ` as Iterator>::Item == Option` + | ------------------------------ ^^^^^^^^ type mismatch resolving ` as Iterator>::Item == Option` + | | + | required by a bound introduced by this call | note: expected this to be `Option` --> $DIR/associated-types-issue-20346.rs:23:17 diff --git a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr index 922cf88a04999..89cdba524be23 100644 --- a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr +++ b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr @@ -1,8 +1,10 @@ error[E0271]: type mismatch resolving `::Y == i32` - --> $DIR/associated-types-multiple-types-one-trait.rs:13:5 + --> $DIR/associated-types-multiple-types-one-trait.rs:13:12 | LL | want_y(t); - | ^^^^^^ expected `i32`, found associated type + | ------ ^ expected `i32`, found associated type + | | + | required by a bound introduced by this call | = note: expected type `i32` found associated type `::Y` @@ -17,10 +19,12 @@ LL | fn have_x_want_y>(t: &T) | +++++++++ error[E0271]: type mismatch resolving `::X == u32` - --> $DIR/associated-types-multiple-types-one-trait.rs:18:5 + --> $DIR/associated-types-multiple-types-one-trait.rs:18:12 | LL | want_x(t); - | ^^^^^^ expected `u32`, found associated type + | ------ ^ expected `u32`, found associated type + | | + | required by a bound introduced by this call | = note: expected type `u32` found associated type `::X` diff --git a/src/test/ui/associated-types/issue-87261.stderr b/src/test/ui/associated-types/issue-87261.stderr index 8db4a49da3c96..f24423dd10666 100644 --- a/src/test/ui/associated-types/issue-87261.stderr +++ b/src/test/ui/associated-types/issue-87261.stderr @@ -1,8 +1,10 @@ error[E0271]: type mismatch resolving `::Associated == ()` - --> $DIR/issue-87261.rs:56:5 + --> $DIR/issue-87261.rs:56:19 | LL | accepts_trait(a); - | ^^^^^^^^^^^^^ expected `()`, found associated type + | ------------- ^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type `::Associated` @@ -17,10 +19,12 @@ LL | A: Trait + 'static, | +++++++++++++++++ error[E0271]: type mismatch resolving `::Associated == ()` - --> $DIR/issue-87261.rs:59:5 + --> $DIR/issue-87261.rs:59:19 | LL | accepts_trait(b); - | ^^^^^^^^^^^^^ expected `()`, found associated type + | ------------- ^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type `::Associated` @@ -33,10 +37,12 @@ LL | fn accepts_trait>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` error[E0271]: type mismatch resolving `::Associated == ()` - --> $DIR/issue-87261.rs:62:5 + --> $DIR/issue-87261.rs:62:19 | LL | accepts_trait(c); - | ^^^^^^^^^^^^^ expected `()`, found associated type + | ------------- ^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type `::Associated` @@ -51,10 +57,12 @@ LL | C: Trait + Foo, | +++++++++++++++++ error[E0271]: type mismatch resolving `::Associated == ()` - --> $DIR/issue-87261.rs:65:5 + --> $DIR/issue-87261.rs:65:19 | LL | accepts_trait(d); - | ^^^^^^^^^^^^^ expected `()`, found associated type + | ------------- ^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type `::Associated` @@ -67,10 +75,12 @@ LL | fn accepts_trait>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` error[E0271]: type mismatch resolving `>::Associated == ()` - --> $DIR/issue-87261.rs:68:5 + --> $DIR/issue-87261.rs:68:27 | LL | accepts_generic_trait(e); - | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | --------------------- ^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type `>::Associated` @@ -85,10 +95,12 @@ LL | E: GenericTrait<(), Associated = ()> + 'static, | +++++++++++++++++ error[E0271]: type mismatch resolving `>::Associated == ()` - --> $DIR/issue-87261.rs:71:5 + --> $DIR/issue-87261.rs:71:27 | LL | accepts_generic_trait(f); - | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | --------------------- ^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type `>::Associated` @@ -103,10 +115,12 @@ LL | F: GenericTrait<(), Associated = ()> + Foo, | +++++++++++++++++ error[E0271]: type mismatch resolving `>::Associated == ()` - --> $DIR/issue-87261.rs:74:5 + --> $DIR/issue-87261.rs:74:27 | LL | accepts_generic_trait(g); - | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | --------------------- ^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type `>::Associated` @@ -119,13 +133,15 @@ LL | fn accepts_generic_trait>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait` error[E0271]: type mismatch resolving `::Associated == ()` - --> $DIR/issue-87261.rs:79:5 + --> $DIR/issue-87261.rs:79:19 | LL | fn returns_opaque() -> impl Trait + 'static { | -------------------- the found opaque type ... LL | accepts_trait(returns_opaque()); - | ^^^^^^^^^^^^^ expected `()`, found associated type + | ------------- ^^^^^^^^^^^^^^^^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type `::Associated` @@ -140,13 +156,15 @@ LL | fn returns_opaque() -> impl Trait + 'static { | +++++++++++++++++ error[E0271]: type mismatch resolving `::Associated == ()` - --> $DIR/issue-87261.rs:82:5 + --> $DIR/issue-87261.rs:82:19 | LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static { | --------------------------- the found opaque type ... LL | accepts_trait(returns_opaque_derived()); - | ^^^^^^^^^^^^^ expected `()`, found associated type + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type `::Associated` @@ -161,13 +179,15 @@ LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static | +++++++++++++++++ error[E0271]: type mismatch resolving `::Associated == ()` - --> $DIR/issue-87261.rs:85:5 + --> $DIR/issue-87261.rs:85:19 | LL | fn returns_opaque_foo() -> impl Trait + Foo { | ---------------- the found opaque type ... LL | accepts_trait(returns_opaque_foo()); - | ^^^^^^^^^^^^^ expected `()`, found associated type + | ------------- ^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type `::Associated` @@ -182,13 +202,15 @@ LL | fn returns_opaque_foo() -> impl Trait + Foo { | +++++++++++++++++ error[E0271]: type mismatch resolving `::Associated == ()` - --> $DIR/issue-87261.rs:88:5 + --> $DIR/issue-87261.rs:88:19 | LL | fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo { | ----------------------- the found opaque type ... LL | accepts_trait(returns_opaque_derived_foo()); - | ^^^^^^^^^^^^^ expected `()`, found associated type + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type `::Associated` @@ -201,13 +223,15 @@ LL | fn accepts_trait>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` error[E0271]: type mismatch resolving ` as GenericTrait<()>>::Associated == ()` - --> $DIR/issue-87261.rs:91:5 + --> $DIR/issue-87261.rs:91:27 | LL | fn returns_opaque_generic() -> impl GenericTrait<()> + 'static { | ------------------------------- the found opaque type ... LL | accepts_generic_trait(returns_opaque_generic()); - | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | --------------------- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type ` as GenericTrait<()>>::Associated` @@ -222,13 +246,15 @@ LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'st | +++++++++++++++++ error[E0271]: type mismatch resolving ` + Foo as GenericTrait<()>>::Associated == ()` - --> $DIR/issue-87261.rs:94:5 + --> $DIR/issue-87261.rs:94:27 | LL | fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo { | --------------------------- the found opaque type ... LL | accepts_generic_trait(returns_opaque_generic_foo()); - | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | --------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type ` + Foo as GenericTrait<()>>::Associated` @@ -243,13 +269,15 @@ LL | fn returns_opaque_generic_foo() -> impl GenericTrait<(), Associated = ()> + | +++++++++++++++++ error[E0271]: type mismatch resolving ` + GenericTrait as GenericTrait<()>>::Associated == ()` - --> $DIR/issue-87261.rs:97:5 + --> $DIR/issue-87261.rs:97:27 | LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait { | ---------------------------------------- the found opaque type ... LL | accepts_generic_trait(returns_opaque_generic_duplicate()); - | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | --------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | | + | required by a bound introduced by this call | = note: expected unit type `()` found associated type ` + GenericTrait as GenericTrait<()>>::Associated` diff --git a/src/test/ui/error-codes/E0271.stderr b/src/test/ui/error-codes/E0271.stderr index 9c9c7237d7145..1e2f4383459e2 100644 --- a/src/test/ui/error-codes/E0271.stderr +++ b/src/test/ui/error-codes/E0271.stderr @@ -1,8 +1,10 @@ error[E0271]: type mismatch resolving `::AssociatedType == u32` - --> $DIR/E0271.rs:10:5 + --> $DIR/E0271.rs:10:9 | LL | foo(3_i8); - | ^^^ type mismatch resolving `::AssociatedType == u32` + | --- ^^^^ type mismatch resolving `::AssociatedType == u32` + | | + | required by a bound introduced by this call | note: expected this to be `u32` --> $DIR/E0271.rs:7:43 diff --git a/src/test/ui/generic-associated-types/issue-74684-2.stderr b/src/test/ui/generic-associated-types/issue-74684-2.stderr index f0e03e73f0b3e..7c2935d32bfd2 100644 --- a/src/test/ui/generic-associated-types/issue-74684-2.stderr +++ b/src/test/ui/generic-associated-types/issue-74684-2.stderr @@ -1,8 +1,10 @@ error[E0271]: type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]` - --> $DIR/issue-74684-2.rs:23:5 + --> $DIR/issue-74684-2.rs:23:9 | LL | bug(Box::new(x)); - | ^^^ type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]` + | --- ^^^^^^^^^^^ type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]` + | | + | required by a bound introduced by this call | note: expected this to be `[u8]` --> $DIR/issue-74684-2.rs:10:18 diff --git a/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs b/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs index ae21dbce01139..e70f6fc3430f6 100644 --- a/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs +++ b/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs @@ -36,9 +36,9 @@ trait Ty<'a> { fn main() { let v = Unit2.m( - //~^ ERROR type mismatch L { //~^ ERROR to be a closure that returns `Unit3`, but it returns `Unit4` + //~| ERROR type mismatch f: |x| { drop(x); Unit4 diff --git a/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr b/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr index 8365fd0c79e1b..51017ffbd4192 100644 --- a/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr +++ b/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr @@ -1,8 +1,16 @@ error[E0271]: type mismatch resolving `for<'r> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V` - --> $DIR/issue-62203-hrtb-ice.rs:38:19 + --> $DIR/issue-62203-hrtb-ice.rs:39:9 | -LL | let v = Unit2.m( - | ^ type mismatch resolving `for<'r> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V` +LL | let v = Unit2.m( + | - required by a bound introduced by this call +LL | / L { +LL | | +LL | | +LL | | f: |x| { +... | +LL | | }, +LL | | }, + | |_________^ type mismatch resolving `for<'r> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V` | note: expected this to be `<_ as Ty<'_>>::V` --> $DIR/issue-62203-hrtb-ice.rs:21:14 @@ -23,16 +31,15 @@ LL | F: for<'r> T0<'r, (>::V,), O = >::V>, | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m` error[E0271]: expected `[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]` to be a closure that returns `Unit3`, but it returns `Unit4` - --> $DIR/issue-62203-hrtb-ice.rs:40:9 + --> $DIR/issue-62203-hrtb-ice.rs:39:9 | LL | let v = Unit2.m( | - required by a bound introduced by this call -LL | LL | / L { LL | | +LL | | LL | | f: |x| { -LL | | drop(x); -LL | | Unit4 +... | LL | | }, LL | | }, | |_________^ expected struct `Unit3`, found struct `Unit4` diff --git a/src/test/ui/intrinsics/const-eval-select-bad.stderr b/src/test/ui/intrinsics/const-eval-select-bad.stderr index e7b7e4a4a910c..1a761ad5441ce 100644 --- a/src/test/ui/intrinsics/const-eval-select-bad.stderr +++ b/src/test/ui/intrinsics/const-eval-select-bad.stderr @@ -52,10 +52,12 @@ LL | G: FnOnce + ~const Destruct, | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select` error[E0271]: expected `fn(i32) -> bool {bar}` to be a fn item that returns `i32`, but it returns `bool` - --> $DIR/const-eval-select-bad.rs:29:5 + --> $DIR/const-eval-select-bad.rs:29:34 | LL | const_eval_select((1,), foo, bar); - | ^^^^^^^^^^^^^^^^^ expected `i32`, found `bool` + | ----------------- ^^^ expected `i32`, found `bool` + | | + | required by a bound introduced by this call | note: required by a bound in `const_eval_select` --> $SRC_DIR/core/src/intrinsics.rs:LL:COL diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.stderr index 4251c1a1ed6cd..00fdb37534613 100644 --- a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.stderr +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-5.stderr @@ -1,8 +1,10 @@ error[E0271]: type mismatch resolving `::T == i64` - --> $DIR/check-trait-object-bounds-5.rs:23:5 + --> $DIR/check-trait-object-bounds-5.rs:23:12 | LL | is_obj(x) - | ^^^^^^ type mismatch resolving `::T == i64` + | ------ ^ type mismatch resolving `::T == i64` + | | + | required by a bound introduced by this call | note: expected this to be `i64` --> $DIR/check-trait-object-bounds-5.rs:9:14 diff --git a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.stderr b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.stderr index 5b23a513eea9b..9b0975e5ed3c3 100644 --- a/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.stderr +++ b/src/test/ui/traits/associated_type_bound/check-trait-object-bounds-6.stderr @@ -1,8 +1,10 @@ error[E0271]: type mismatch resolving `::T == i64` - --> $DIR/check-trait-object-bounds-6.rs:20:5 + --> $DIR/check-trait-object-bounds-6.rs:20:12 | LL | is_obj(x) - | ^^^^^^ type mismatch resolving `::T == i64` + | ------ ^ type mismatch resolving `::T == i64` + | | + | required by a bound introduced by this call | note: expected this to be `i64` --> $DIR/check-trait-object-bounds-6.rs:9:14 From 54edf1863e120f9b2f3bf1a3f2b5040e9c8ca476 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 13 Aug 2022 07:14:54 +0000 Subject: [PATCH 7/8] Also do it for generics --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 37 ++++++++++--------- .../associated-types-eq-hr.stderr | 8 ++-- .../enforce-supertrait-projection.stderr | 4 +- .../pointee-tail-is-generic-errors.stderr | 8 ++-- 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 1f2dfc30ae03b..bdb7c90aca3b0 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1756,25 +1756,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let hir::ExprKind::Call(path, _) = &call_expr.kind { if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &path.kind { for error in errors { - if let ty::PredicateKind::Trait(predicate) = - error.obligation.predicate.kind().skip_binder() + let self_ty = match error.obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Trait(predicate) => predicate.self_ty(), + ty::PredicateKind::Projection(predicate) => { + predicate.projection_ty.self_ty() + } + _ => continue, + }; + // If any of the type arguments in this path segment caused the + // `FulfillmentError`, point at its span (#61860). + for arg in path + .segments + .iter() + .filter_map(|seg| seg.args.as_ref()) + .flat_map(|a| a.args.iter()) { - // If any of the type arguments in this path segment caused the - // `FulfillmentError`, point at its span (#61860). - for arg in path - .segments - .iter() - .filter_map(|seg| seg.args.as_ref()) - .flat_map(|a| a.args.iter()) + if let hir::GenericArg::Type(hir_ty) = &arg + && let Some(ty) = + self.typeck_results.borrow().node_type_opt(hir_ty.hir_id) + && self.resolve_vars_if_possible(ty) == self_ty { - if let hir::GenericArg::Type(hir_ty) = &arg - && let Some(ty) = - self.typeck_results.borrow().node_type_opt(hir_ty.hir_id) - && self.resolve_vars_if_possible(ty) == predicate.self_ty() - { - error.obligation.cause.span = hir_ty.span; - break; - } + error.obligation.cause.span = hir_ty.span; + break; } } } diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr index b306ae273e870..6cff403b318c1 100644 --- a/src/test/ui/associated-types/associated-types-eq-hr.stderr +++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr @@ -1,8 +1,8 @@ error[E0271]: type mismatch resolving `for<'x> >::A == &'x isize` - --> $DIR/associated-types-eq-hr.rs:87:5 + --> $DIR/associated-types-eq-hr.rs:87:11 | LL | foo::(); - | ^^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> >::A == &'x isize` + | ^^^^^^^^^^ type mismatch resolving `for<'x> >::A == &'x isize` | note: expected this to be `&isize` --> $DIR/associated-types-eq-hr.rs:26:14 @@ -21,10 +21,10 @@ LL | T: for<'x> TheTrait<&'x isize, A = &'x isize>, | ^^^^^^^^^^^^^ required by this bound in `foo` error[E0271]: type mismatch resolving `for<'x> >::A == &'x usize` - --> $DIR/associated-types-eq-hr.rs:91:5 + --> $DIR/associated-types-eq-hr.rs:91:11 | LL | bar::(); - | ^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> >::A == &'x usize` + | ^^^^^^^^^ type mismatch resolving `for<'x> >::A == &'x usize` | note: expected this to be `&usize` --> $DIR/associated-types-eq-hr.rs:14:14 diff --git a/src/test/ui/traits/object/enforce-supertrait-projection.stderr b/src/test/ui/traits/object/enforce-supertrait-projection.stderr index eab42ca568a04..cbf0938665447 100644 --- a/src/test/ui/traits/object/enforce-supertrait-projection.stderr +++ b/src/test/ui/traits/object/enforce-supertrait-projection.stderr @@ -1,12 +1,12 @@ error[E0271]: type mismatch resolving ` as SuperTrait>::A == B` - --> $DIR/enforce-supertrait-projection.rs:9:5 + --> $DIR/enforce-supertrait-projection.rs:9:17 | LL | fn transmute(x: A) -> B { | - - expected type parameter | | | found type parameter LL | foo::>(x) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A` + | ^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A` | = note: expected type parameter `B` found type parameter `A` diff --git a/src/test/ui/traits/pointee-tail-is-generic-errors.stderr b/src/test/ui/traits/pointee-tail-is-generic-errors.stderr index 8456f84562ff2..0c3d7060dd7c3 100644 --- a/src/test/ui/traits/pointee-tail-is-generic-errors.stderr +++ b/src/test/ui/traits/pointee-tail-is-generic-errors.stderr @@ -1,8 +1,8 @@ error[E0271]: type mismatch resolving `::Metadata == ()` - --> $DIR/pointee-tail-is-generic-errors.rs:13:5 + --> $DIR/pointee-tail-is-generic-errors.rs:13:15 | LL | is_thin::(); - | ^^^^^^^^^^^^ expected `()`, found associated type + | ^ expected `()`, found associated type | = note: expected unit type `()` found associated type `::Metadata` @@ -15,13 +15,13 @@ LL | fn is_thin + ?Sized>() {} | ^^^^^^^^^^^^^ required by this bound in `is_thin` error[E0271]: type mismatch resolving `::Metadata == ()` - --> $DIR/pointee-tail-is-generic-errors.rs:16:5 + --> $DIR/pointee-tail-is-generic-errors.rs:16:15 | LL | type Opaque = impl std::fmt::Debug + ?Sized; | ----------------------------- the found opaque type ... LL | is_thin::(); - | ^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | ^^^^^^ expected `()`, found associated type | = note: expected unit type `()` found associated type `::Metadata` From 84f0d5e460786d071ff3598637c24137ef866509 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Mon, 15 Aug 2022 16:42:58 +0900 Subject: [PATCH 8/8] use `create_snapshot_for_diagnostic` instead of `clone` for `Parser` --- compiler/rustc_parse/src/parser/item.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 72c23776d3399..65ebaf1539f13 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2260,7 +2260,7 @@ impl<'a> Parser<'a> { (pat, this.parse_ty_for_param()?) } else { debug!("parse_param_general ident_to_pat"); - let parser_snapshot_before_ty = this.clone(); + let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic(); this.eat_incorrect_doc_comment_for_param_type(); let mut ty = this.parse_ty_for_param(); if ty.is_ok() @@ -2283,7 +2283,7 @@ impl<'a> Parser<'a> { // Recover from attempting to parse the argument as a type without pattern. Err(err) => { err.cancel(); - *this = parser_snapshot_before_ty; + this.restore_snapshot(parser_snapshot_before_ty); this.recover_arg_parse()? } }