diff options
| author | bors <bors@rust-lang.org> | 2021-09-16 02:00:08 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-09-16 02:00:08 +0000 |
| commit | 34327f6eee06835f81a26765a70ad51d44343ba3 (patch) | |
| tree | 2dea940ec9bd534bee053ac3ce0f6570d0b31e50 /compiler | |
| parent | 4aed1abb706a31331fd8b612ca400935aeddd0e0 (diff) | |
| parent | 1da3c1d88ae46e8464042fc2f397a21acd496e61 (diff) | |
| download | rust-34327f6eee06835f81a26765a70ad51d44343ba3.tar.gz rust-34327f6eee06835f81a26765a70ad51d44343ba3.zip | |
Auto merge of #88992 - Manishearth:rollup-k9hijii, r=Manishearth
Rollup of 8 pull requests
Successful merges:
- #87320 (Introduce -Z remap-cwd-prefix switch)
- #88690 (Accept `m!{ .. }.method()` and `m!{ .. }?` statements. )
- #88775 (Revert anon union parsing)
- #88841 (feat(rustc_typeck): suggest removing bad parens in `(recv.method)()`)
- #88907 (Highlight the `const fn` if error happened because of a bound on the impl block)
- #88915 (`Wrapping<T>` has the same layout and ABI as `T`)
- #88933 (Remove implementation of `min_align_of` intrinsic)
- #88951 (Update books)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_ast/src/ast.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/mut_visit.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/visit.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/item.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/lib.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/ast_validation.rs | 68 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/feature_gate.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_ast_pretty/src/pprust/state.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/intrinsics.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/check_consts/ops.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_feature/src/active.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/tests.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 38 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/stmt.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/ty.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_session/src/config.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_session/src/options.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/expr.rs | 23 |
19 files changed, 87 insertions, 165 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index b92c5fa0727..c27ab810a4c 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1902,10 +1902,6 @@ pub enum TyKind { Never, /// A tuple (`(A, B, C, D,...)`). Tup(Vec<P<Ty>>), - /// An anonymous struct type i.e. `struct { foo: Type }` - AnonymousStruct(Vec<FieldDef>, bool), - /// An anonymous union type i.e. `union { bar: Type }` - AnonymousUnion(Vec<FieldDef>, bool), /// A path (`module::module::...::Type`), optionally /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`. /// diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 2ec941cbb24..ba86036577a 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -484,9 +484,6 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) { visit_vec(bounds, |bound| vis.visit_param_bound(bound)); } TyKind::MacCall(mac) => vis.visit_mac_call(mac), - TyKind::AnonymousStruct(fields, ..) | TyKind::AnonymousUnion(fields, ..) => { - fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); - } } vis.visit_span(span); visit_lazy_tts(tokens, vis); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index c30f711b397..b38031042e0 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -407,9 +407,6 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) { TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression), TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {} TyKind::MacCall(ref mac) => visitor.visit_mac_call(mac), - TyKind::AnonymousStruct(ref fields, ..) | TyKind::AnonymousUnion(ref fields, ..) => { - walk_list!(visitor, visit_field_def, fields) - } TyKind::Never | TyKind::CVarArgs => {} } } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index b7497c713f3..a77e3e1997f 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -748,10 +748,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - pub(super) fn lower_field_def( - &mut self, - (index, f): (usize, &FieldDef), - ) -> hir::FieldDef<'hir> { + fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'hir> { let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind { let t = self.lower_path_ty( &f.ty, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 8d731d7a578..4cf54b07dbe 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1301,15 +1301,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let kind = match t.kind { TyKind::Infer => hir::TyKind::Infer, TyKind::Err => hir::TyKind::Err, - // FIXME(unnamed_fields): IMPLEMENTATION IN PROGRESS - TyKind::AnonymousStruct(ref _fields, _recovered) => { - self.sess.struct_span_err(t.span, "anonymous structs are unimplemented").emit(); - hir::TyKind::Err - } - TyKind::AnonymousUnion(ref _fields, _recovered) => { - self.sess.struct_span_err(t.span, "anonymous unions are unimplemented").emit(); - hir::TyKind::Err - } TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)), TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), TyKind::Rptr(ref region, ref mt) => { diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 11153284cad..24108f779c8 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -193,11 +193,6 @@ impl<'a> AstValidator<'a> { } } } - TyKind::AnonymousStruct(ref fields, ..) | TyKind::AnonymousUnion(ref fields, ..) => { - self.with_banned_assoc_ty_bound(|this| { - walk_list!(this, visit_struct_field_def, fields) - }); - } _ => visit::walk_ty(self, t), } } @@ -205,7 +200,6 @@ impl<'a> AstValidator<'a> { fn visit_struct_field_def(&mut self, field: &'a FieldDef) { if let Some(ident) = field.ident { if ident.name == kw::Underscore { - self.check_anonymous_field(field); self.visit_vis(&field.vis); self.visit_ident(ident); self.visit_ty_common(&field.ty); @@ -251,66 +245,6 @@ impl<'a> AstValidator<'a> { err.emit(); } - fn check_anonymous_field(&self, field: &FieldDef) { - let FieldDef { ty, .. } = field; - match &ty.kind { - TyKind::AnonymousStruct(..) | TyKind::AnonymousUnion(..) => { - // We already checked for `kw::Underscore` before calling this function, - // so skip the check - } - TyKind::Path(..) => { - // If the anonymous field contains a Path as type, we can't determine - // if the path is a valid struct or union, so skip the check - } - _ => { - let msg = "unnamed fields can only have struct or union types"; - let label = "not a struct or union"; - self.err_handler() - .struct_span_err(field.span, msg) - .span_label(ty.span, label) - .emit(); - } - } - } - - fn deny_anonymous_struct(&self, ty: &Ty) { - match &ty.kind { - TyKind::AnonymousStruct(..) => { - self.err_handler() - .struct_span_err( - ty.span, - "anonymous structs are not allowed outside of unnamed struct or union fields", - ) - .span_label(ty.span, "anonymous struct declared here") - .emit(); - } - TyKind::AnonymousUnion(..) => { - self.err_handler() - .struct_span_err( - ty.span, - "anonymous unions are not allowed outside of unnamed struct or union fields", - ) - .span_label(ty.span, "anonymous union declared here") - .emit(); - } - _ => {} - } - } - - fn deny_anonymous_field(&self, field: &FieldDef) { - if let Some(ident) = field.ident { - if ident.name == kw::Underscore { - self.err_handler() - .struct_span_err( - field.span, - "anonymous fields are not allowed outside of structs or unions", - ) - .span_label(ident.span, "anonymous field declared here") - .emit() - } - } - } - fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Ident>, bool)) { for Param { pat, .. } in &decl.inputs { match pat.kind { @@ -1081,7 +1015,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_ty(&mut self, ty: &'a Ty) { self.visit_ty_common(ty); - self.deny_anonymous_struct(ty); self.walk_ty(ty) } @@ -1096,7 +1029,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } fn visit_field_def(&mut self, s: &'a FieldDef) { - self.deny_anonymous_field(s); visit::walk_field_def(self, s) } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 1defb65ed87..30bc4edd7e6 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -668,7 +668,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { // involved, so we only emit errors where there are no other parsing errors. gate_all!(destructuring_assignment, "destructuring assignments are unstable"); } - gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented"); // All uses of `gate_all!` below this point were added in #65742, // and subsequently disabled (with the non-early gating readded). diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 3cf04be160c..c24882086e1 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -985,14 +985,6 @@ impl<'a> State<'a> { } self.pclose(); } - ast::TyKind::AnonymousStruct(ref fields, ..) => { - self.head("struct"); - self.print_record_struct_body(&fields, ty.span); - } - ast::TyKind::AnonymousUnion(ref fields, ..) => { - self.head("union"); - self.print_record_struct_body(&fields, ty.span); - } ast::TyKind::Paren(ref typ) => { self.popen(); self.print_type(typ); @@ -1413,7 +1405,12 @@ impl<'a> State<'a> { } } - crate fn print_record_struct_body(&mut self, fields: &[ast::FieldDef], span: rustc_span::Span) { + crate fn print_record_struct_body( + &mut self, + fields: &Vec<ast::FieldDef>, + span: rustc_span::Span, + ) { + self.nbsp(); self.bopen(); self.hardbreak_if_not_bol(); @@ -1462,7 +1459,6 @@ impl<'a> State<'a> { } ast::VariantData::Struct(ref fields, ..) => { self.print_where_clause(&generics.where_clause); - self.nbsp(); self.print_record_struct_body(fields, span); } } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index b032ee96ce7..698742fe98c 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -62,15 +62,10 @@ crate fn eval_nullary_intrinsic<'tcx>( ensure_monomorphic_enough(tcx, tp_ty)?; ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env)) } - sym::min_align_of | sym::pref_align_of => { + sym::pref_align_of => { // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?; - let n = match name { - sym::pref_align_of => layout.align.pref.bytes(), - sym::min_align_of => layout.align.abi.bytes(), - _ => bug!(), - }; - ConstValue::from_machine_usize(n, &tcx) + ConstValue::from_machine_usize(layout.align.pref.bytes(), &tcx) } sym::type_id => { ensure_monomorphic_enough(tcx, tp_ty)?; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 8923d989b29..2a296750838 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -599,12 +599,21 @@ pub mod ty { } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { - feature_err( + let mut builder = feature_err( &ccx.tcx.sess.parse_sess, sym::const_fn_trait_bound, span, "trait bounds other than `Sized` on const fn parameters are unstable", - ) + ); + + match ccx.fn_sig() { + Some(fn_sig) if !fn_sig.span.contains(span) => { + builder.span_label(fn_sig.span, "function declared as const here"); + } + _ => {} + } + + builder } } diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 366ed715434..efa93c18636 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -638,9 +638,6 @@ declare_features! ( /// Allows specifying the as-needed link modifier (active, native_link_modifiers_as_needed, "1.53.0", Some(81490), None), - /// Allows unnamed fields of struct and union type - (incomplete, unnamed_fields, "1.53.0", Some(49804), None), - /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns. (active, more_qualified_paths, "1.54.0", Some(86935), None), diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 81433e57102..cfe13b1fd4e 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -754,6 +754,7 @@ fn test_debugging_options_tracking_hash() { tracked!(profiler_runtime, "abc".to_string()); tracked!(relax_elf_relocations, Some(true)); tracked!(relro_level, Some(RelroLevel::Full)); + tracked!(remap_cwd_prefix, Some(PathBuf::from("abc"))); tracked!(simulate_remapped_rust_src_base, Some(PathBuf::from("/rustc/abc"))); tracked!(report_delayed_bugs, true); tracked!(sanitizer, SanitizerSet::ADDRESS); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 04a7948e8c9..0e2222bf840 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1247,7 +1247,7 @@ impl<'a> Parser<'a> { Ok((class_name, ItemKind::Union(vdata, generics))) } - pub(super) fn parse_record_struct_body( + fn parse_record_struct_body( &mut self, adt_ty: &str, ) -> PResult<'a, (Vec<FieldDef>, /* recovered */ bool)> { @@ -1481,28 +1481,22 @@ impl<'a> Parser<'a> { fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> { let (ident, is_raw) = self.ident_or_err()?; if !is_raw && ident.is_reserved() { - if ident.name == kw::Underscore { - self.sess.gated_spans.gate(sym::unnamed_fields, lo); + let err = if self.check_fn_front_matter(false) { + // We use `parse_fn` to get a span for the function + if let Err(mut db) = self.parse_fn(&mut Vec::new(), |_| true, lo) { + db.delay_as_bug(); + } + let mut err = self.struct_span_err( + lo.to(self.prev_token.span), + &format!("functions are not allowed in {} definitions", adt_ty), + ); + err.help("unlike in C++, Java, and C#, functions are declared in `impl` blocks"); + err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information"); + err } else { - let err = if self.check_fn_front_matter(false) { - // We use `parse_fn` to get a span for the function - if let Err(mut db) = self.parse_fn(&mut Vec::new(), |_| true, lo) { - db.delay_as_bug(); - } - let mut err = self.struct_span_err( - lo.to(self.prev_token.span), - &format!("functions are not allowed in {} definitions", adt_ty), - ); - err.help( - "unlike in C++, Java, and C#, functions are declared in `impl` blocks", - ); - err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information"); - err - } else { - self.expected_ident_found() - }; - return Err(err); - } + self.expected_ident_found() + }; + return Err(err); } self.bump(); Ok(ident) diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 25dcb4a112d..9ec6effeb4e 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -155,17 +155,20 @@ impl<'a> Parser<'a> { let mac = MacCall { path, args, prior_type_ascription: self.last_type_ascription }; - let kind = if delim == token::Brace || self.token == token::Semi || self.token == token::Eof - { - StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None })) - } else { - // Since none of the above applied, this is an expression statement macro. - let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac), AttrVec::new()); - let e = self.maybe_recover_from_bad_qpath(e, true)?; - let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?; - let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?; - StmtKind::Expr(e) - }; + let kind = + if (delim == token::Brace && self.token != token::Dot && self.token != token::Question) + || self.token == token::Semi + || self.token == token::Eof + { + StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None })) + } else { + // Since none of the above applied, this is an expression statement macro. + let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac), AttrVec::new()); + let e = self.maybe_recover_from_bad_qpath(e, true)?; + let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?; + let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?; + StmtKind::Expr(e) + }; Ok(self.mk_stmt(lo.to(hi), kind)) } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 299fc916ac9..98400372c36 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -226,19 +226,6 @@ impl<'a> Parser<'a> { } } else if self.eat_keyword(kw::Impl) { self.parse_impl_ty(&mut impl_dyn_multi)? - } else if self.token.is_keyword(kw::Union) - && self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace)) - { - self.bump(); - let (fields, recovered) = self.parse_record_struct_body("union")?; - let span = lo.to(self.prev_token.span); - self.sess.gated_spans.gate(sym::unnamed_fields, span); - TyKind::AnonymousUnion(fields, recovered) - } else if self.eat_keyword(kw::Struct) { - let (fields, recovered) = self.parse_record_struct_body("struct")?; - let span = lo.to(self.prev_token.span); - self.sess.gated_spans.gate(sym::unnamed_fields, span); - TyKind::AnonymousStruct(fields, recovered) } else if self.is_explicit_dyn_type() { self.parse_dyn_ty(&mut impl_dyn_multi)? } else if self.eat_lt() { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index fdedb7e6a4a..32aa035e1cd 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1920,9 +1920,10 @@ fn parse_extern_dep_specs( fn parse_remap_path_prefix( matches: &getopts::Matches, + debugging_opts: &DebuggingOptions, error_format: ErrorOutputType, ) -> Vec<(PathBuf, PathBuf)> { - matches + let mut mapping: Vec<(PathBuf, PathBuf)> = matches .opt_strs("remap-path-prefix") .into_iter() .map(|remap| match remap.rsplit_once('=') { @@ -1932,7 +1933,15 @@ fn parse_remap_path_prefix( ), Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)), }) - .collect() + .collect(); + match &debugging_opts.remap_cwd_prefix { + Some(to) => match std::env::current_dir() { + Ok(cwd) => mapping.push((cwd, to.clone())), + Err(_) => (), + }, + None => (), + }; + mapping } pub fn build_session_options(matches: &getopts::Matches) -> Options { @@ -2077,7 +2086,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let crate_name = matches.opt_str("crate-name"); - let remap_path_prefix = parse_remap_path_prefix(matches, error_format); + let remap_path_prefix = parse_remap_path_prefix(matches, &debugging_opts, error_format); let pretty = parse_pretty(&debugging_opts, error_format); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index bb29a87035e..8110afe75fa 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1250,6 +1250,8 @@ options! { "whether ELF relocations can be relaxed"), relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED], "choose which RELRO level to use"), + remap_cwd_prefix: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], + "remap paths under the current working directory to this path prefix"), simulate_remapped_rust_src_base: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], "simulate the effect of remap-debuginfo = true at bootstrapping by remapping path \ to rust's source base directory. only meant for testing purposes"), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1df5b8cd2cc..4b416f29f26 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1359,7 +1359,6 @@ symbols! { unix, unlikely, unmarked_api, - unnamed_fields, unpin, unreachable, unreachable_code, diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index d578fac4cdb..f4e3c8e0d9f 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1842,7 +1842,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr_t ); err.span_label(field.span, "method, not a field"); - if !self.expr_in_place(expr.hir_id) { + let expr_is_call = + if let hir::Node::Expr(hir::Expr { kind: ExprKind::Call(callee, _args), .. }) = + self.tcx.hir().get(self.tcx.hir().get_parent_node(expr.hir_id)) + { + expr.hir_id == callee.hir_id + } else { + false + }; + let expr_snippet = + self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap_or(String::new()); + if expr_is_call && expr_snippet.starts_with("(") && expr_snippet.ends_with(")") { + let after_open = expr.span.lo() + rustc_span::BytePos(1); + let before_close = expr.span.hi() - rustc_span::BytePos(1); + err.multipart_suggestion( + "remove wrapping parentheses to call the method", + vec![ + (expr.span.with_hi(after_open), String::new()), + (expr.span.with_lo(before_close), String::new()), + ], + Applicability::MachineApplicable, + ); + } else if !self.expr_in_place(expr.hir_id) { self.suggest_method_call( &mut err, "use parentheses to call the method", |
