diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6176120b3016b..eb0506c459afa 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -470,6 +470,7 @@ pub enum StashKey { /// Maybe there was a typo where a comma was forgotten before /// FRU syntax MaybeFruTypo, + CallAssocMethod, } fn default_track_diagnostic(_: &Diagnostic) {} diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 8215031063827..f204d59d00556 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -347,7 +347,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { assert!(self_ty.is_some()); } } else { - assert!(self_ty.is_none() && parent_substs.is_empty()); + assert!(self_ty.is_none()); } let arg_count = Self::check_generic_arg_count( @@ -1821,7 +1821,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Check if we have an enum variant. let mut variant_resolution = None; - if let ty::Adt(adt_def, _) = qself_ty.kind() { + if let ty::Adt(adt_def, adt_substs) = qself_ty.kind() { if adt_def.is_enum() { let variant_def = adt_def .variants() @@ -1923,8 +1923,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let Some(assoc_ty_did) = self.lookup_assoc_ty(assoc_ident, hir_ref_id, span, impl_) else { continue; }; - // FIXME(inherent_associated_types): This does not substitute parameters. - let ty = tcx.type_of(assoc_ty_did); + let item_substs = self.create_substs_for_associated_item( + span, + assoc_ty_did, + assoc_segment, + adt_substs, + ); + let ty = tcx.bound_type_of(assoc_ty_did).subst(tcx, item_substs); return Ok((ty, DefKind::AssocTy, assoc_ty_did)); } } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 7daed74e9de83..b065ace6bf5e1 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1544,7 +1544,7 @@ fn check_fn_or_method<'tcx>( check_where_clauses(wfcx, span, def_id); check_return_position_impl_trait_in_trait_bounds( - tcx, + wfcx, def_id, sig.output(), hir_decl.output.span(), @@ -1580,13 +1580,14 @@ fn check_fn_or_method<'tcx>( /// Basically `check_associated_type_bounds`, but separated for now and should be /// deduplicated when RPITITs get lowered into real associated items. -#[tracing::instrument(level = "trace", skip(tcx))] +#[tracing::instrument(level = "trace", skip(wfcx))] fn check_return_position_impl_trait_in_trait_bounds<'tcx>( - tcx: TyCtxt<'tcx>, + wfcx: &WfCheckingCtxt<'_, 'tcx>, fn_def_id: LocalDefId, fn_output: Ty<'tcx>, span: Span, ) { + let tcx = wfcx.tcx(); if let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id()) && assoc_item.container == ty::AssocItemContainer::TraitContainer { @@ -1596,22 +1597,20 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>( && tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder && tcx.impl_trait_in_trait_parent(proj.item_def_id) == fn_def_id.to_def_id() { - // Create a new context, since we want the opaque's ParamEnv and not the parent's. let span = tcx.def_span(proj.item_def_id); - enter_wf_checking_ctxt(tcx, span, proj.item_def_id.expect_local(), |wfcx| { - let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id); - let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| { - let normalized_bound = wfcx.normalize(span, None, bound); - traits::wf::predicate_obligations( - wfcx.infcx, - wfcx.param_env, - wfcx.body_id, - normalized_bound, - bound_span, - ) - }); - wfcx.register_obligations(wf_obligations); + let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id); + let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| { + let bound = ty::EarlyBinder(bound).subst(tcx, proj.substs); + let normalized_bound = wfcx.normalize(span, None, bound); + traits::wf::predicate_obligations( + wfcx.infcx, + wfcx.param_env, + wfcx.body_id, + normalized_bound, + bound_span, + ) }); + wfcx.register_obligations(wf_obligations); } } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 0c5bbb3e20be3..4a112e80f1d98 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -528,6 +528,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span); let ty = match res { Res::Err => { + self.suggest_assoc_method_call(segs); let e = self.tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 727fab9e7aa1e..9ba4ddfd5cf7f 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -5,6 +5,7 @@ use crate::errors; use crate::FnCtxt; use rustc_ast::ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::StashKey; use rustc_errors::{ pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, @@ -13,6 +14,8 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; +use rustc_hir::PatKind::Binding; +use rustc_hir::PathSegment; use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::{ type_variable::{TypeVariableOrigin, TypeVariableOriginKind}, @@ -35,11 +38,11 @@ use rustc_trait_selection::traits::{ FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, }; -use std::cmp::Ordering; -use std::iter; - use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope}; use super::{CandidateSource, MethodError, NoMatchData}; +use rustc_hir::intravisit::Visitor; +use std::cmp::Ordering; +use std::iter; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool { @@ -1462,6 +1465,61 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { false } + /// For code `rect::area(...)`, + /// if `rect` is a local variable and `area` is a valid assoc method for it, + /// we try to suggest `rect.area()` + pub(crate) fn suggest_assoc_method_call(&self, segs: &[PathSegment<'_>]) { + debug!("suggest_assoc_method_call segs: {:?}", segs); + let [seg1, seg2] = segs else { return; }; + let Some(mut diag) = + self.tcx.sess.diagnostic().steal_diagnostic(seg1.ident.span, StashKey::CallAssocMethod) + else { return }; + + let map = self.infcx.tcx.hir(); + let body = map.body(rustc_hir::BodyId { hir_id: self.body_id }); + struct LetVisitor<'a> { + result: Option<&'a hir::Expr<'a>>, + ident_name: Symbol, + } + + impl<'v> Visitor<'v> for LetVisitor<'v> { + fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) { + if let hir::StmtKind::Local(hir::Local { pat, init, .. }) = &ex.kind { + if let Binding(_, _, ident, ..) = pat.kind && + ident.name == self.ident_name { + self.result = *init; + } + } + hir::intravisit::walk_stmt(self, ex); + } + } + + let mut visitor = LetVisitor { result: None, ident_name: seg1.ident.name }; + visitor.visit_body(&body); + + let parent = self.tcx.hir().get_parent_node(seg1.hir_id); + if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) && + let Some(expr) = visitor.result { + let self_ty = self.node_ty(expr.hir_id); + let probe = self.lookup_probe( + seg2.ident, + self_ty, + call_expr, + ProbeScope::TraitsInScope, + ); + if probe.is_ok() { + let sm = self.infcx.tcx.sess.source_map(); + diag.span_suggestion_verbose( + sm.span_extend_while(seg1.ident.span.shrink_to_hi(), |c| c == ':').unwrap(), + "you may have meant to call an instance method", + ".".to_string(), + Applicability::MaybeIncorrect + ); + } + } + diag.emit(); + } + /// Suggest calling a method on a field i.e. `a.field.bar()` instead of `a.bar()` fn suggest_calling_method_on_field( &self, diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index ff1ddfd97dfc6..42197e6379749 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -72,14 +72,22 @@ impl<'a> Parser<'a> { Ok(Some(if self.token.is_keyword(kw::Let) { self.parse_local_mk(lo, attrs, capture_semi, force_collect)? - } else if self.is_kw_followed_by_ident(kw::Mut) { - self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::MissingLet)? - } else if self.is_kw_followed_by_ident(kw::Auto) { + } else if self.is_kw_followed_by_ident(kw::Mut) && self.may_recover() { + self.recover_stmt_local_after_let(lo, attrs, InvalidVariableDeclarationSub::MissingLet)? + } else if self.is_kw_followed_by_ident(kw::Auto) && self.may_recover() { self.bump(); // `auto` - self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotAuto)? - } else if self.is_kw_followed_by_ident(sym::var) { + self.recover_stmt_local_after_let( + lo, + attrs, + InvalidVariableDeclarationSub::UseLetNotAuto, + )? + } else if self.is_kw_followed_by_ident(sym::var) && self.may_recover() { self.bump(); // `var` - self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotVar)? + self.recover_stmt_local_after_let( + lo, + attrs, + InvalidVariableDeclarationSub::UseLetNotVar, + )? } else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() { // We have avoided contextual keywords like `union`, items with `crate` visibility, // or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something @@ -213,13 +221,21 @@ impl<'a> Parser<'a> { } } - fn recover_stmt_local( + fn recover_stmt_local_after_let( &mut self, lo: Span, attrs: AttrWrapper, subdiagnostic: fn(Span) -> InvalidVariableDeclarationSub, ) -> PResult<'a, Stmt> { - let stmt = self.recover_local_after_let(lo, attrs)?; + let stmt = + self.collect_tokens_trailing_token(attrs, ForceCollect::Yes, |this, attrs| { + let local = this.parse_local(attrs)?; + // FIXME - maybe capture semicolon in recovery? + Ok(( + this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Local(local)), + TrailingToken::None, + )) + })?; self.sess.emit_err(InvalidVariableDeclaration { span: lo, sub: subdiagnostic(lo) }); Ok(stmt) } @@ -243,17 +259,6 @@ impl<'a> Parser<'a> { }) } - fn recover_local_after_let(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a, Stmt> { - self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { - let local = this.parse_local(attrs)?; - // FIXME - maybe capture semicolon in recovery? - Ok(( - this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Local(local)), - TrailingToken::None, - )) - }) - } - /// Parses a local variable declaration. fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P> { let lo = self.prev_token.span; diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index bc3a710e84bd0..f6b6cf3a94c18 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1840,13 +1840,16 @@ impl<'a> Resolver<'a> { (format!("use of undeclared type `{}`", ident), suggestion) } else { - let suggestion = if ident.name == sym::alloc { - Some(( + let mut suggestion = None; + if ident.name == sym::alloc { + suggestion = Some(( vec![], String::from("add `extern crate alloc` to use the `alloc` crate"), Applicability::MaybeIncorrect, )) - } else { + } + + suggestion = suggestion.or_else(|| { self.find_similarly_named_module_or_crate(ident.name, &parent_scope.module).map( |sugg| { ( @@ -1856,7 +1859,7 @@ impl<'a> Resolver<'a> { ) }, ) - }; + }); (format!("use of undeclared crate or module `{}`", ident), suggestion) } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 2d2408c061ee2..51a53f7b37cc2 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3365,13 +3365,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // Before we start looking for candidates, we have to get our hands // on the type user is trying to perform invocation on; basically: // we're transforming `HashMap::new` into just `HashMap`. - let path = match path.split_last() { + let prefix_path = match path.split_last() { Some((_, path)) if !path.is_empty() => path, _ => return Some(parent_err), }; let (mut err, candidates) = - this.smart_resolve_report_errors(path, path_span, PathSource::Type, None); + this.smart_resolve_report_errors(prefix_path, path_span, PathSource::Type, None); // There are two different error messages user might receive at // this point: @@ -3415,11 +3415,23 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { if this.should_report_errs() { if candidates.is_empty() { - // When there is no suggested imports, we can just emit the error - // and suggestions immediately. Note that we bypass the usually error - // reporting routine (ie via `self.r.report_error`) because we need - // to post-process the `ResolutionError` above. - err.emit(); + if path.len() == 2 && prefix_path.len() == 1 { + // Delay to check whether methond name is an associated function or not + // ``` + // let foo = Foo {}; + // foo::bar(); // possibly suggest to foo.bar(); + //``` + err.stash( + prefix_path[0].ident.span, + rustc_errors::StashKey::CallAssocMethod, + ); + } else { + // When there is no suggested imports, we can just emit the error + // and suggestions immediately. Note that we bypass the usually error + // reporting routine (ie via `self.r.report_error`) because we need + // to post-process the `ResolutionError` above. + err.emit(); + } } else { // If there are suggested imports, the error reporting is delayed this.r.use_injections.push(UseError { @@ -3428,7 +3440,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { def_id, instead: false, suggestion: None, - path: path.into(), + path: prefix_path.into(), is_call: source.is_call(), }); } diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index fe8a028dfd3ad..399727e6bd4a1 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -11,15 +11,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -117,9 +108,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" dependencies = [ "cfg-if", "crossbeam-utils", @@ -127,9 +118,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -138,26 +129,24 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.8" +version = "0.9.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "lazy_static", "memoffset", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.8" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ "cfg-if", - "lazy_static", ] [[package]] @@ -379,9 +368,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ "autocfg", ] @@ -447,14 +436,14 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "pretty_assertions" -version = "0.7.2" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cab0e7c02cf376875e9335e0ba1da535775beb5450d21e1dffca068818ed98b" +checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755" dependencies = [ - "ansi_term", "ctor", "diff", "output_vt100", + "yansi", ] [[package]] @@ -477,11 +466,10 @@ dependencies = [ [[package]] name = "rayon" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b" dependencies = [ - "autocfg", "crossbeam-deque", "either", "rayon-core", @@ -489,9 +477,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.3" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -803,3 +791,9 @@ checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c" dependencies = [ "lzma-sys", ] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 8751a71caf1b4..ccc7ec1fce9f0 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -72,7 +72,7 @@ features = [ ] [dev-dependencies] -pretty_assertions = "0.7" +pretty_assertions = "1.2" [features] build-metrics = ["sysinfo"] diff --git a/src/test/ui/associated-consts/issue-47814.rs b/src/test/ui/associated-consts/issue-47814.rs new file mode 100644 index 0000000000000..a28b1c00113c9 --- /dev/null +++ b/src/test/ui/associated-consts/issue-47814.rs @@ -0,0 +1,14 @@ +struct ArpIPv4<'a> { + s: &'a u8 +} + +impl<'a> ArpIPv4<'a> { + const LENGTH: usize = 20; + + pub fn to_buffer() -> [u8; Self::LENGTH] { + //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants + unimplemented!() + } +} + +fn main() {} diff --git a/src/test/ui/associated-consts/issue-47814.stderr b/src/test/ui/associated-consts/issue-47814.stderr new file mode 100644 index 0000000000000..2e4ddb81166b4 --- /dev/null +++ b/src/test/ui/associated-consts/issue-47814.stderr @@ -0,0 +1,14 @@ +error: generic `Self` types are currently not permitted in anonymous constants + --> $DIR/issue-47814.rs:8:32 + | +LL | pub fn to_buffer() -> [u8; Self::LENGTH] { + | ^^^^ + | +note: not a concrete type + --> $DIR/issue-47814.rs:5:10 + | +LL | impl<'a> ArpIPv4<'a> { + | ^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/associated-inherent-types/struct-generics.rs b/src/test/ui/associated-inherent-types/struct-generics.rs new file mode 100644 index 0000000000000..8952b37917308 --- /dev/null +++ b/src/test/ui/associated-inherent-types/struct-generics.rs @@ -0,0 +1,15 @@ +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S(T); + +impl S { + type P = T; +} + +fn main() { + type A = S<()>::P; + let _: A = (); +} diff --git a/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr index 5c8d64fc6cb4c..f1f0d7e5907d3 100644 --- a/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr +++ b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr @@ -4,11 +4,11 @@ error[E0311]: the parameter type `U` may not live long enough LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^^^^^^^ | -note: the parameter type `U` must be valid for the anonymous lifetime as defined here... +note: the parameter type `U` must be valid for the anonymous lifetime defined here... --> $DIR/async-generics-and-bounds.rs:12:18 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^ + | ^^^^^ note: ...so that the reference type `&(T, U)` does not outlive the data it points at --> $DIR/async-generics-and-bounds.rs:12:28 | @@ -21,11 +21,11 @@ error[E0311]: the parameter type `T` may not live long enough LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^^^^^^^ | -note: the parameter type `T` must be valid for the anonymous lifetime as defined here... +note: the parameter type `T` must be valid for the anonymous lifetime defined here... --> $DIR/async-generics-and-bounds.rs:12:18 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^ + | ^^^^^ note: ...so that the reference type `&(T, U)` does not outlive the data it points at --> $DIR/async-generics-and-bounds.rs:12:28 | diff --git a/src/test/ui/async-await/in-trait/async-generics.stderr b/src/test/ui/async-await/in-trait/async-generics.stderr index 6ae73d9e3a601..2f05564564cd2 100644 --- a/src/test/ui/async-await/in-trait/async-generics.stderr +++ b/src/test/ui/async-await/in-trait/async-generics.stderr @@ -4,11 +4,11 @@ error[E0311]: the parameter type `U` may not live long enough LL | async fn foo(&self) -> &(T, U); | ^^^^^^^ | -note: the parameter type `U` must be valid for the anonymous lifetime as defined here... +note: the parameter type `U` must be valid for the anonymous lifetime defined here... --> $DIR/async-generics.rs:9:18 | LL | async fn foo(&self) -> &(T, U); - | ^ + | ^^^^^ note: ...so that the reference type `&(T, U)` does not outlive the data it points at --> $DIR/async-generics.rs:9:28 | @@ -21,11 +21,11 @@ error[E0311]: the parameter type `T` may not live long enough LL | async fn foo(&self) -> &(T, U); | ^^^^^^^ | -note: the parameter type `T` must be valid for the anonymous lifetime as defined here... +note: the parameter type `T` must be valid for the anonymous lifetime defined here... --> $DIR/async-generics.rs:9:18 | LL | async fn foo(&self) -> &(T, U); - | ^ + | ^^^^^ note: ...so that the reference type `&(T, U)` does not outlive the data it points at --> $DIR/async-generics.rs:9:28 | diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs index 3f7448cecd157..d5481d277e40a 100644 --- a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs +++ b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs @@ -1,5 +1,4 @@ -// check-fail -// known-bug: #102682 +// check-pass // edition: 2021 #![feature(async_fn_in_trait)] diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr deleted file mode 100644 index 0f02420274333..0000000000000 --- a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0309]: the parameter type `Self` may not live long enough - --> $DIR/async-lifetimes-and-bounds.rs:11:43 - | -LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized; - | ^^^^^^^^^^^^^^^^^ - | - = help: consider adding an explicit lifetime bound `Self: 'a`... - = note: ...so that the reference type `&'a Self` does not outlive the data it points at - -error[E0309]: the parameter type `T` may not live long enough - --> $DIR/async-lifetimes-and-bounds.rs:11:43 - | -LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized; - | ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at - | -help: consider adding an explicit lifetime bound... - | -LL | trait MyTrait<'a, 'b, T: 'b> { - | ++++ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.rs b/src/test/ui/async-await/in-trait/async-lifetimes.rs index acbac471cf7e8..f298e45d2390b 100644 --- a/src/test/ui/async-await/in-trait/async-lifetimes.rs +++ b/src/test/ui/async-await/in-trait/async-lifetimes.rs @@ -1,5 +1,4 @@ -// check-fail -// known-bug: #102682 +// check-pass // edition: 2021 #![feature(async_fn_in_trait)] diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.stderr b/src/test/ui/async-await/in-trait/async-lifetimes.stderr deleted file mode 100644 index 9a7d294bb1766..0000000000000 --- a/src/test/ui/async-await/in-trait/async-lifetimes.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0309]: the parameter type `Self` may not live long enough - --> $DIR/async-lifetimes.rs:9:43 - | -LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T); - | ^^^^^^^^^^^^^^^^^ - | - = help: consider adding an explicit lifetime bound `Self: 'a`... - = note: ...so that the reference type `&'a Self` does not outlive the data it points at - -error[E0309]: the parameter type `T` may not live long enough - --> $DIR/async-lifetimes.rs:9:43 - | -LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T); - | ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at - | -help: consider adding an explicit lifetime bound... - | -LL | trait MyTrait<'a, 'b, T: 'b> { - | ++++ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/async-await/in-trait/implied-bounds.rs b/src/test/ui/async-await/in-trait/implied-bounds.rs new file mode 100644 index 0000000000000..52bceb3cc5cd6 --- /dev/null +++ b/src/test/ui/async-await/in-trait/implied-bounds.rs @@ -0,0 +1,13 @@ +// check-pass +// edition: 2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +trait TcpStack { + type Connection<'a>: Sized where Self: 'a; + fn connect<'a>(&'a self) -> Self::Connection<'a>; + async fn async_connect<'a>(&'a self) -> Self::Connection<'a>; +} + +fn main() {} diff --git a/src/test/ui/impl-trait/in-trait/where-clause.rs b/src/test/ui/impl-trait/in-trait/where-clause.rs new file mode 100644 index 0000000000000..87bac519cf304 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/where-clause.rs @@ -0,0 +1,24 @@ +// check-pass +// edition: 2021 + +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +use std::fmt::Debug; + +trait Foo { + fn foo<'a>(&'a self) -> impl Debug + where + Item: 'a; +} + +impl Foo for D { + fn foo<'a>(&'a self) -> impl Debug + where + Item: 'a, + { + self.clone() + } +} + +fn main() {} diff --git a/src/test/ui/macros/issue-103529.rs b/src/test/ui/macros/issue-103529.rs new file mode 100644 index 0000000000000..fa05baed7fc8e --- /dev/null +++ b/src/test/ui/macros/issue-103529.rs @@ -0,0 +1,13 @@ +macro_rules! m { + ($s:stmt) => {} +} + +m! { mut x } +//~^ ERROR expected expression, found keyword `mut` +//~| ERROR expected a statement +m! { auto x } +//~^ ERROR invalid variable declaration +m! { var x } +//~^ ERROR invalid variable declaration + +fn main() {} diff --git a/src/test/ui/macros/issue-103529.stderr b/src/test/ui/macros/issue-103529.stderr new file mode 100644 index 0000000000000..61e322afc7709 --- /dev/null +++ b/src/test/ui/macros/issue-103529.stderr @@ -0,0 +1,39 @@ +error: expected expression, found keyword `mut` + --> $DIR/issue-103529.rs:5:6 + | +LL | m! { mut x } + | ^^^ expected expression + +error: expected a statement + --> $DIR/issue-103529.rs:5:10 + | +LL | ($s:stmt) => {} + | ------- while parsing argument for this `stmt` macro fragment +... +LL | m! { mut x } + | ^ + +error: invalid variable declaration + --> $DIR/issue-103529.rs:8:6 + | +LL | m! { auto x } + | ^^^^ + | +help: write `let` instead of `auto` to introduce a new variable + | +LL | m! { let x } + | ~~~ + +error: invalid variable declaration + --> $DIR/issue-103529.rs:10:6 + | +LL | m! { var x } + | ^^^ + | +help: write `let` instead of `var` to introduce a new variable + | +LL | m! { let x } + | ~~~ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/resolve/bad-module.stderr b/src/test/ui/resolve/bad-module.stderr index 581a661981460..558760c6793ab 100644 --- a/src/test/ui/resolve/bad-module.stderr +++ b/src/test/ui/resolve/bad-module.stderr @@ -1,15 +1,15 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `thing` - --> $DIR/bad-module.rs:2:15 - | -LL | let foo = thing::len(Vec::new()); - | ^^^^^ use of undeclared crate or module `thing` - error[E0433]: failed to resolve: use of undeclared crate or module `foo` --> $DIR/bad-module.rs:5:15 | LL | let foo = foo::bar::baz(); | ^^^ use of undeclared crate or module `foo` +error[E0433]: failed to resolve: use of undeclared crate or module `thing` + --> $DIR/bad-module.rs:2:15 + | +LL | let foo = thing::len(Vec::new()); + | ^^^^^ use of undeclared crate or module `thing` + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/resolve/issue-101749-2.rs b/src/test/ui/resolve/issue-101749-2.rs new file mode 100644 index 0000000000000..4d3d469447c2b --- /dev/null +++ b/src/test/ui/resolve/issue-101749-2.rs @@ -0,0 +1,16 @@ +struct Rectangle { + width: i32, + height: i32, +} +impl Rectangle { + fn new(width: i32, height: i32) -> Self { + Self { width, height } + } +} + +fn main() { + let rect = Rectangle::new(3, 4); + // `area` is not implemented for `Rectangle`, so this should not suggest + let _ = rect::area(); + //~^ ERROR failed to resolve: use of undeclared crate or module `rect` +} diff --git a/src/test/ui/resolve/issue-101749-2.stderr b/src/test/ui/resolve/issue-101749-2.stderr new file mode 100644 index 0000000000000..370d4b14540d6 --- /dev/null +++ b/src/test/ui/resolve/issue-101749-2.stderr @@ -0,0 +1,9 @@ +error[E0433]: failed to resolve: use of undeclared crate or module `rect` + --> $DIR/issue-101749-2.rs:14:13 + | +LL | let _ = rect::area(); + | ^^^^ use of undeclared crate or module `rect` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/resolve/issue-101749.fixed b/src/test/ui/resolve/issue-101749.fixed new file mode 100644 index 0000000000000..3e5544296e462 --- /dev/null +++ b/src/test/ui/resolve/issue-101749.fixed @@ -0,0 +1,19 @@ +// run-rustfix +struct Rectangle { + width: i32, + height: i32, +} +impl Rectangle { + fn new(width: i32, height: i32) -> Self { + Self { width, height } + } + fn area(&self) -> i32 { + self.height * self.width + } +} + +fn main() { + let rect = Rectangle::new(3, 4); + let _ = rect.area(); + //~^ ERROR failed to resolve: use of undeclared crate or module `rect` +} diff --git a/src/test/ui/resolve/issue-101749.rs b/src/test/ui/resolve/issue-101749.rs new file mode 100644 index 0000000000000..fd67ccab6fa75 --- /dev/null +++ b/src/test/ui/resolve/issue-101749.rs @@ -0,0 +1,19 @@ +// run-rustfix +struct Rectangle { + width: i32, + height: i32, +} +impl Rectangle { + fn new(width: i32, height: i32) -> Self { + Self { width, height } + } + fn area(&self) -> i32 { + self.height * self.width + } +} + +fn main() { + let rect = Rectangle::new(3, 4); + let _ = rect::area(); + //~^ ERROR failed to resolve: use of undeclared crate or module `rect` +} diff --git a/src/test/ui/resolve/issue-101749.stderr b/src/test/ui/resolve/issue-101749.stderr new file mode 100644 index 0000000000000..dd29d7fc05103 --- /dev/null +++ b/src/test/ui/resolve/issue-101749.stderr @@ -0,0 +1,14 @@ +error[E0433]: failed to resolve: use of undeclared crate or module `rect` + --> $DIR/issue-101749.rs:17:13 + | +LL | let _ = rect::area(); + | ^^^^ use of undeclared crate or module `rect` + | +help: you may have meant to call an instance method + | +LL | let _ = rect.area(); + | ~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/resolve/issue-24968.stderr b/src/test/ui/resolve/issue-24968.stderr index 7e539d258048e..82f5a1d5b57b3 100644 --- a/src/test/ui/resolve/issue-24968.stderr +++ b/src/test/ui/resolve/issue-24968.stderr @@ -1,15 +1,3 @@ -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions - --> $DIR/issue-24968.rs:21:19 - | -LL | const FOO2: u32 = Self::bar(); - | ^^^^ `Self` is only available in impls, traits, and type definitions - -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions - --> $DIR/issue-24968.rs:27:22 - | -LL | static FOO_S2: u32 = Self::bar(); - | ^^^^ `Self` is only available in impls, traits, and type definitions - error[E0411]: cannot find type `Self` in this scope --> $DIR/issue-24968.rs:3:11 | @@ -51,6 +39,18 @@ LL | static FOO_S: Self = 0; | | | `Self` not allowed in a static item +error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions + --> $DIR/issue-24968.rs:21:19 + | +LL | const FOO2: u32 = Self::bar(); + | ^^^^ `Self` is only available in impls, traits, and type definitions + +error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions + --> $DIR/issue-24968.rs:27:22 + | +LL | static FOO_S2: u32 = Self::bar(); + | ^^^^ `Self` is only available in impls, traits, and type definitions + error: aborting due to 7 previous errors Some errors have detailed explanations: E0411, E0433. diff --git a/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr b/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr index ff7cf531c06dd..89b69e1409967 100644 --- a/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr +++ b/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr @@ -1,3 +1,24 @@ +error[E0433]: failed to resolve: could not find `Struc` in `module` + --> $DIR/typo-suggestion-mistyped-in-path.rs:35:13 + | +LL | module::Struc::foo(); + | ^^^^^ + | | + | could not find `Struc` in `module` + | help: a struct with a similar name exists: `Struct` + +error[E0599]: no function or associated item named `fob` found for struct `Struct` in the current scope + --> $DIR/typo-suggestion-mistyped-in-path.rs:23:13 + | +LL | struct Struct; + | ------------- function or associated item `fob` not found for this struct +... +LL | Struct::fob(); + | ^^^ + | | + | function or associated item not found in `Struct` + | help: there is an associated function with a similar name: `foo` + error[E0433]: failed to resolve: use of undeclared type `Struc` --> $DIR/typo-suggestion-mistyped-in-path.rs:27:5 | @@ -18,15 +39,6 @@ help: there is a crate or module with a similar name LL | module::foo(); | ~~~~~~ -error[E0433]: failed to resolve: could not find `Struc` in `module` - --> $DIR/typo-suggestion-mistyped-in-path.rs:35:13 - | -LL | module::Struc::foo(); - | ^^^^^ - | | - | could not find `Struc` in `module` - | help: a struct with a similar name exists: `Struct` - error[E0433]: failed to resolve: use of undeclared type `Trai` --> $DIR/typo-suggestion-mistyped-in-path.rs:39:5 | @@ -36,18 +48,6 @@ LL | Trai::foo(); | use of undeclared type `Trai` | help: a trait with a similar name exists: `Trait` -error[E0599]: no function or associated item named `fob` found for struct `Struct` in the current scope - --> $DIR/typo-suggestion-mistyped-in-path.rs:23:13 - | -LL | struct Struct; - | ------------- function or associated item `fob` not found for this struct -... -LL | Struct::fob(); - | ^^^ - | | - | function or associated item not found in `Struct` - | help: there is an associated function with a similar name: `foo` - error: aborting due to 5 previous errors Some errors have detailed explanations: E0433, E0599. diff --git a/src/test/ui/resolve/use_suggestion.stderr b/src/test/ui/resolve/use_suggestion.stderr index 58cb659e82203..54ad853831f36 100644 --- a/src/test/ui/resolve/use_suggestion.stderr +++ b/src/test/ui/resolve/use_suggestion.stderr @@ -1,9 +1,3 @@ -error[E0433]: failed to resolve: use of undeclared type `GooMap` - --> $DIR/use_suggestion.rs:3:14 - | -LL | let x2 = GooMap::new(); - | ^^^^^^ use of undeclared type `GooMap` - error[E0433]: failed to resolve: use of undeclared type `HashMap` --> $DIR/use_suggestion.rs:2:14 | @@ -32,6 +26,12 @@ error[E0412]: cannot find type `GooMap` in this scope LL | let y2: GooMap; | ^^^^^^ not found in this scope +error[E0433]: failed to resolve: use of undeclared type `GooMap` + --> $DIR/use_suggestion.rs:3:14 + | +LL | let x2 = GooMap::new(); + | ^^^^^^ use of undeclared type `GooMap` + error: aborting due to 4 previous errors Some errors have detailed explanations: E0412, E0433. diff --git a/src/test/ui/suggestions/crate-or-module-typo.stderr b/src/test/ui/suggestions/crate-or-module-typo.stderr index e8250c9fa5ff4..98b88b4fb9202 100644 --- a/src/test/ui/suggestions/crate-or-module-typo.stderr +++ b/src/test/ui/suggestions/crate-or-module-typo.stderr @@ -20,12 +20,6 @@ help: there is a crate or module with a similar name LL | use bar::bar; | ~~~ -error[E0433]: failed to resolve: use of undeclared crate or module `bar` - --> $DIR/crate-or-module-typo.rs:6:20 - | -LL | pub fn bar() { bar::baz(); } - | ^^^ use of undeclared crate or module `bar` - error[E0433]: failed to resolve: use of undeclared crate or module `st` --> $DIR/crate-or-module-typo.rs:14:10 | @@ -37,6 +31,12 @@ help: there is a crate or module with a similar name LL | bar: std::cell::Cell | ~~~ +error[E0433]: failed to resolve: use of undeclared crate or module `bar` + --> $DIR/crate-or-module-typo.rs:6:20 + | +LL | pub fn bar() { bar::baz(); } + | ^^^ use of undeclared crate or module `bar` + error: aborting due to 4 previous errors Some errors have detailed explanations: E0432, E0433.