diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md
index 994afc625d1f2e12f545d6c8151d736b9af67fd3..412774fd1ae5b5a0f351fb8edd11ae460b3d18a2 100644
--- a/docs/usage/configuration-options.md
+++ b/docs/usage/configuration-options.md
@@ -412,6 +412,7 @@ This is an advanced field, and it's recommend you seek a config review before ap
 
 Currently, this config option only works with these managers:
 
+- `cargo`
 - `helmv3`
 - `npm`
 - `nuget`
diff --git a/lib/modules/manager/cargo/extract.spec.ts b/lib/modules/manager/cargo/extract.spec.ts
index 629f2fb61c32120ba865c6eb94a88b72cf52b21f..cf80672e7cf76cb982a66c190c94743d30013533 100644
--- a/lib/modules/manager/cargo/extract.spec.ts
+++ b/lib/modules/manager/cargo/extract.spec.ts
@@ -585,5 +585,19 @@ replace-with = "mcorbin"
         expect.not.objectContaining({ lockedVersion: expect.anything() }),
       ]);
     });
+
+    it('should extract project version', async () => {
+      const cargotoml = codeBlock`
+        [package]
+        name = "test"
+        version = "0.1.0"
+        edition = "2021"
+        [dependencies]
+        syn = "2.0"
+        `;
+
+      const res = await extractPackageFile(cargotoml, 'Cargo.toml', config);
+      expect(res?.packageFileVersion).toBe('0.1.0');
+    });
   });
 });
diff --git a/lib/modules/manager/cargo/extract.ts b/lib/modules/manager/cargo/extract.ts
index d5ec4ded972ff22689fa72f3ae9bab163202ebd4..cd0d3f746fbe4e0f23ba4b1f1d3f6fc1706f22dc 100644
--- a/lib/modules/manager/cargo/extract.ts
+++ b/lib/modules/manager/cargo/extract.ts
@@ -224,6 +224,7 @@ export async function extractPackageFile(
   }
   /*
     There are the following sections in Cargo.toml:
+    [package]
     [dependencies]
     [dev-dependencies]
     [build-dependencies]
@@ -284,11 +285,18 @@ export async function extractPackageFile(
   if (!deps.length) {
     return null;
   }
+
+  const packageSection = cargoManifest.package;
+  let version: string | undefined = undefined;
+  if (packageSection) {
+    version = packageSection.version;
+  }
+
   const lockFileName = await findLocalSiblingOrParent(
     packageFile,
     'Cargo.lock',
   );
-  const res: PackageFileContent = { deps };
+  const res: PackageFileContent = { deps, packageFileVersion: version };
   if (lockFileName) {
     logger.debug(
       `Found lock file ${lockFileName} for packageFile: ${packageFile}`,
diff --git a/lib/modules/manager/cargo/index.ts b/lib/modules/manager/cargo/index.ts
index adbba5cfb253b91848a341cb0e16978bcecea3ba..fb62a10969670738415244a747e5a6e934eb556b 100644
--- a/lib/modules/manager/cargo/index.ts
+++ b/lib/modules/manager/cargo/index.ts
@@ -3,6 +3,7 @@ import { CrateDatasource } from '../../datasource/crate';
 import * as cargoVersioning from '../../versioning/cargo';
 import { updateArtifacts } from './artifacts';
 import { extractPackageFile } from './extract';
+export { bumpPackageVersion } from './update';
 export { getRangeStrategy } from './range';
 export { updateLockedDependency } from './update-locked';
 
diff --git a/lib/modules/manager/cargo/types.ts b/lib/modules/manager/cargo/types.ts
index 41208ad64e274429e859361aeca8c424f8478d8e..68bfa4740432a846df29c61dce151688c99490c5 100644
--- a/lib/modules/manager/cargo/types.ts
+++ b/lib/modules/manager/cargo/types.ts
@@ -1,5 +1,10 @@
 import type { DEFAULT_REGISTRY_URL } from './utils';
 
+export interface CargoPackage {
+  /** Semver version */
+  version: string;
+}
+
 export interface CargoDep {
   /** Path on disk to the crate sources */
   path?: string;
@@ -26,6 +31,7 @@ export interface CargoSection {
 export interface CargoManifest extends CargoSection {
   target?: Record<string, CargoSection>;
   workspace?: CargoSection;
+  package?: CargoPackage;
 }
 
 export interface CargoConfig {
diff --git a/lib/modules/manager/cargo/update.spec.ts b/lib/modules/manager/cargo/update.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..66adeb550f7617bdfea600c6ba051a6130b2311e
--- /dev/null
+++ b/lib/modules/manager/cargo/update.spec.ts
@@ -0,0 +1,59 @@
+import { codeBlock } from 'common-tags';
+import * as projectUpdater from '.';
+
+describe('modules/manager/cargo/update', () => {
+  describe('bumpPackageVersion()', () => {
+    const content = codeBlock`
+      [package]
+      name = "test"
+      version = "0.0.2"
+    `;
+
+    it('increments', () => {
+      const { bumpedContent } = projectUpdater.bumpPackageVersion(
+        content,
+        '0.0.2',
+        'patch',
+      );
+      const expected = content.replace('0.0.2', '0.0.3');
+      expect(bumpedContent).toEqual(expected);
+    });
+
+    it('no ops', () => {
+      const { bumpedContent } = projectUpdater.bumpPackageVersion(
+        content,
+        '0.0.1',
+        'patch',
+      );
+      expect(bumpedContent).toEqual(content);
+    });
+
+    it('updates', () => {
+      const { bumpedContent } = projectUpdater.bumpPackageVersion(
+        content,
+        '0.0.1',
+        'minor',
+      );
+      const expected = content.replace('0.0.2', '0.1.0');
+      expect(bumpedContent).toEqual(expected);
+    });
+
+    it('returns content if bumping errors', () => {
+      const { bumpedContent } = projectUpdater.bumpPackageVersion(
+        content,
+        '0.0.2',
+        true as any,
+      );
+      expect(bumpedContent).toEqual(content);
+    });
+
+    it('does not bump version if version is not a semantic version', () => {
+      const { bumpedContent } = projectUpdater.bumpPackageVersion(
+        content,
+        '1',
+        'patch',
+      );
+      expect(bumpedContent).toEqual(content);
+    });
+  });
+});
diff --git a/lib/modules/manager/cargo/update.ts b/lib/modules/manager/cargo/update.ts
new file mode 100644
index 0000000000000000000000000000000000000000..196044d75f44da2387407129ce326202e488d171
--- /dev/null
+++ b/lib/modules/manager/cargo/update.ts
@@ -0,0 +1,55 @@
+import semver, { ReleaseType } from 'semver';
+import { logger } from '../../../logger';
+import { regEx } from '../../../util/regex';
+import type { BumpPackageVersionResult } from '../types';
+
+export function bumpPackageVersion(
+  content: string,
+  currentValue: string,
+  bumpVersion: ReleaseType,
+): BumpPackageVersionResult {
+  logger.debug(
+    { bumpVersion, currentValue },
+    'Checking if we should bump Cargo.toml version',
+  );
+  let bumpedContent = content;
+
+  if (!semver.valid(currentValue)) {
+    logger.warn(
+      { currentValue },
+      'Unable to bump Cargo.toml version, not a valid semver',
+    );
+    return { bumpedContent };
+  }
+
+  try {
+    const newCrateVersion = semver.inc(currentValue, bumpVersion);
+    if (!newCrateVersion) {
+      throw new Error('semver inc failed');
+    }
+
+    logger.debug({ newCrateVersion });
+
+    bumpedContent = content.replace(
+      regEx(`^(?<version>version[ \\t]*=[ \\t]*['"])[^'"]*`, 'm'),
+      `$<version>${newCrateVersion}`,
+    );
+
+    if (bumpedContent === content) {
+      logger.debug('Version was already bumped');
+    } else {
+      logger.debug('Bumped Cargo.toml version');
+    }
+  } catch (err) {
+    logger.warn(
+      {
+        content,
+        currentValue,
+        bumpVersion,
+      },
+      'Failed to bumpVersion',
+    );
+  }
+
+  return { bumpedContent };
+}